<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aditya Mahajan</title>
    <description>The latest articles on Forem by Aditya Mahajan (@adityamahajan).</description>
    <link>https://forem.com/adityamahajan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1881165%2Fc1e7602d-22ff-43a2-8e35-0a60fb06df8c.png</url>
      <title>Forem: Aditya Mahajan</title>
      <link>https://forem.com/adityamahajan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adityamahajan"/>
    <language>en</language>
    <item>
      <title>Java Generics : What and Why?</title>
      <dc:creator>Aditya Mahajan</dc:creator>
      <pubDate>Thu, 08 Aug 2024 18:30:10 +0000</pubDate>
      <link>https://forem.com/adityamahajan/java-generics-what-and-why-3poh</link>
      <guid>https://forem.com/adityamahajan/java-generics-what-and-why-3poh</guid>
      <description>&lt;h2&gt;
  
  
  What are Java Generics?
&lt;/h2&gt;

&lt;p&gt;According to Javadocs &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A generic type is a generic class or interface that is parameterized over types.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now assuming you already know what is class and interface in Java(&lt;a href="https://docs.oracle.com/javase/tutorial/java/javaOO/index.html" rel="noopener noreferrer"&gt;if not, please have a look here&lt;/a&gt;), we will go through what does parameterized over types means. &lt;/p&gt;

&lt;p&gt;Now suppose we want to create a class, with a field name as &lt;code&gt;fullName&lt;/code&gt; and field &lt;strong&gt;type&lt;/strong&gt; as &lt;code&gt;Object&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ThisIsNonGenericClass {

  private Object fullName;

  public ThisIsNonGenericClass(Object fullName) {
    this.fullName = fullName;
  }

  public Object getFullName() {
    return fullName;
  }

  public void setFullName(Object fullName) {
    this.fullName = fullName;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, here we are using &lt;code&gt;Object&lt;/code&gt; 3 times. &lt;/p&gt;

&lt;p&gt;Now if we want to print value for field &lt;code&gt;fullName&lt;/code&gt;, we need&lt;br&gt;
&lt;em&gt;casting&lt;/em&gt; to &lt;code&gt;String&lt;/code&gt;, since the compiler requires, explicit cast, for getting &lt;code&gt;String&lt;/code&gt; out of &lt;code&gt;Object&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ThisIsDevArticle {
  public static void main(String[] args) {
    ThisIsNonGenericClass thisIsNonGenericClass = new ThisIsNonGenericClass("AdityaMahajan");
    String name = (String) thisIsNonGenericClass.getFullName();
    System.out.println("This is name: " + name);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets introduce a &lt;strong&gt;parameter&lt;/strong&gt; &lt;code&gt;T&lt;/code&gt; at class level. This can replace the &lt;strong&gt;type&lt;/strong&gt; for field as well as the return &lt;strong&gt;type&lt;/strong&gt; of methods. In this way we just introduced a &lt;strong&gt;parameter&lt;/strong&gt; to a class and made the class &lt;strong&gt;type parameterized&lt;/strong&gt;. Here &lt;code&gt;T&lt;/code&gt; has replaced &lt;code&gt;Object&lt;/code&gt; when compared to &lt;code&gt;ThisIsNonGenericClass&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ThisIsGenericClass&amp;lt;T&amp;gt; {
  private T fullName;

  public T getFullName() {
    return fullName;
  }

  public ThisIsGenericClass(T fullName) {
    this.fullName = fullName;
  }

  public void setFullName(T fullName) {
    this.fullName = fullName;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets try to print value for field &lt;code&gt;fullName&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ThisIsDevArticle {
  public static void main(String[] args) {
    ThisIsGenericClass&amp;lt;String&amp;gt; thisIsGenericClass = new ThisIsGenericClass&amp;lt;&amp;gt;("AdityaMahajan");
    String name = thisIsGenericClass.getFullName();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's the difference now? &lt;/p&gt;

&lt;p&gt;By specifying the &lt;strong&gt;type&lt;/strong&gt; as &lt;strong&gt;String&lt;/strong&gt; here, &lt;code&gt;ThisIsGenericClass&amp;lt;String&amp;gt; thisIsGenericClass&lt;/code&gt;, we were able to tell the class what &lt;strong&gt;type&lt;/strong&gt; to use and now the &lt;strong&gt;parameter&lt;/strong&gt; is identified as &lt;strong&gt;String&lt;/strong&gt; and the &lt;code&gt;getFullName&lt;/code&gt; is returning &lt;strong&gt;String&lt;/strong&gt;. We even reduced the need of &lt;em&gt;casting&lt;/em&gt;. Voila! This is Java Generics, and one advantage here is &lt;a href="https://docs.oracle.com/javase/tutorial/java/generics/why.html" rel="noopener noreferrer"&gt;avoiding casting&lt;/a&gt;, by specifying the &lt;strong&gt;type&lt;/strong&gt; argument as &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quick Terminology here.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ThisIsGenericClass&amp;lt;T&amp;gt;&lt;/code&gt; : &lt;code&gt;T&lt;/code&gt; here is called &lt;strong&gt;Type Parameter&lt;/strong&gt;.&lt;br&gt;
&lt;code&gt;ThisIsGenericClass&amp;lt;String&amp;gt;&lt;/code&gt; : &lt;code&gt;String&lt;/code&gt; here is called &lt;strong&gt;Type argument&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another callout is the diamond operator &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; at the right can be empty as long as &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; has &lt;code&gt;String&lt;/code&gt; in the left.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ThisIsGenericClass&amp;lt;String&amp;gt; thisIsGenericClass = new ThisIsGenericClass&amp;lt;&amp;gt;("AdityaMahajan");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler is smart enough to figure out itself when the class is instantiated. This is called &lt;code&gt;type inference&lt;/code&gt;, &lt;a href="https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html" rel="noopener noreferrer"&gt;more on this here&lt;/a&gt;. It is equivalent to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ThisIsGenericClass&amp;lt;String&amp;gt; thisIsGenericClass = new ThisIsGenericClass&amp;lt;String&amp;gt;("AdityaMahajan");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could always use multiple parameters in the class or interface like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ThisIsGenericClassWithMutipleParameters&amp;lt;T1,T2&amp;gt; {

  private T1 fullName;

  public T1 getFullName() {
    return fullName;
  }

  public void setFullName(T1 fullName) {
    this.fullName = fullName;
  }

  private T2 age;

  public T2 getAge() {
    return age;
  }

  public void setAge(T2 age) {
    this.age = age;
  }

public ThisIsGenericClassWithMutipleParameters(T1 fullName, T2 age) {
    this.fullName = fullName;
    this.age = age;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use above with something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ThisIsGenericClassWithMutipleParameters&amp;lt;String,Integer&amp;gt; thisIsGenericClass2 
        = new ThisIsGenericClassWithMutipleParameters&amp;lt;&amp;gt;("AdityaMahajan", 26);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generic Methods
&lt;/h2&gt;

&lt;p&gt;We can also use parameters in methods as well, and in next example, see how this can avoid runtime exception, &lt;a href="https://docs.oracle.com/javase/tutorial/java/generics/why.html" rel="noopener noreferrer"&gt;catching compile time errors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Suppose we have a method to calculate total length of string accepting &lt;code&gt;List&lt;/code&gt; as method argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public int getTotalLengthOfString(List names) {
    int len = 0 ;
    for(int i = 0; i&amp;lt;names.size(); i++){
      String name = (String) names.get(i);
      len += name.length();
    }
    return len;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we do something like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List names = new ArrayList&amp;lt;&amp;gt;();
names.add("Medvedev");
names.add("Tsitsipas");
System.out.println("This is total length : " + getTotalLengthOfString(names));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is total length : 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However let say, for some reason we added another item, here an &lt;code&gt;Integer&lt;/code&gt; to the &lt;code&gt;List&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String nameWithoutCast = thisIsGenericClass.getFullName();
List names = new ArrayList&amp;lt;&amp;gt;();
names.add("Medvedev");
names.add("Tsitsipas");
names.add(32);
System.out.println("This is total length : " + getTotalLengthOfString(names));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And running the program led to a &lt;code&gt;ClassCastException&lt;/code&gt;, which occurs while we run a program, a child class of &lt;code&gt;RuntimeException&lt;/code&gt;. Following is the output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to avoid this?
&lt;/h3&gt;

&lt;p&gt;Now lets update the method parameter from &lt;code&gt;List&lt;/code&gt; to &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt;. Now doing this will also make us change the instantiation from &lt;br&gt;
&lt;code&gt;List names = new ArrayList&amp;lt;&amp;gt;()&lt;/code&gt; to &lt;code&gt;List&amp;lt;String&amp;gt; names = new ArrayList&amp;lt;&amp;gt;()&lt;/code&gt;. And if you see, we dont even need casting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public int getTotalLengthOfString(List&amp;lt;String&amp;gt; names) {
    int len = 0 ;
    for(int i =0; i&amp;lt;names.size(); i++){
      len += name.length();
    }
    return len;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if someone try something like this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;String&amp;gt; names = new ArrayList&amp;lt;&amp;gt;();
names.add("Medvedev");
names.add("Tsitsipas");
names.add(32);
System.out.println("This is total length : " + getTotalLengthOfString(names));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;compiler will complain and ask developer to fix it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixjtajabplgnwv246p1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixjtajabplgnwv246p1e.png" alt="Compiler complaining! strong type check!" width="596" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this we made the compiler do tighter type checks, during compile time, and avoiding &lt;code&gt;ClassCastException&lt;/code&gt; during runtime. Another advantage of using Generics!&lt;/p&gt;

&lt;p&gt;Some terminology here : &lt;br&gt;
&lt;code&gt;List&amp;lt;T&amp;gt; names&lt;/code&gt; : Here we are using generic-type. And is a parameterized type with no argument.&lt;br&gt;
&lt;code&gt;List&amp;lt;String&amp;gt; names&lt;/code&gt; : Here we are using generic-type. And is a parameterized type with argument &lt;code&gt;String&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;List names&lt;/code&gt; : Here the names is raw-type of &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;, with no parameters, no arguments.&lt;/p&gt;

&lt;h2&gt;
  
  
  That is all for introduction, let me know your thoughts in the comments.
&lt;/h2&gt;

&lt;p&gt;Reference&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.oracle.com/javase/tutorial/java/generics/why.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/tutorial/java/generics/why.html&lt;/a&gt; and others in the same section&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=CKWw7J5MsyY" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=CKWw7J5MsyY&lt;/a&gt; by Jakob Jenkov&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/javase/tutorial/java/generics/QandE/generics-answers.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/javase/tutorial/java/generics/QandE/generics-answers.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>java</category>
      <category>backend</category>
      <category>typesafe</category>
    </item>
  </channel>
</rss>
