Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How and when does Class T change from Integer to String rather than showing error/exception

What i have done is to just get to know how Generics works in Java. I have written the following code:

public class Test {

    public static void main(String... args) throws Exception{  
        Foo o = new Foo<Integer>(new Integer(5));
        o.fun();
    }
}       

class Foo<T> {

    private T t;

    public Foo(T t) throws InstantiationException, IllegalAccessException{
       System.out.println("1. T is "+t.getClass());
       this.t = (T)"test";
       System.out.println("2. T is "+t.getClass());
   }

   void fun(){
       System.out.println("3. T is "+t.getClass()+" t = "+t);
   }
}

And output is

1. T is class java.lang.Integer
2. T is Still class java.lang.Integer
3. T is class java.lang.String t = test

My question is Why this is changing Class from Integer to String and not showing error/exception.

And second thing is that when I write t = 9; in function fun(), it shows:

incompatible types
required: T
found:    java.lang.Integer

How do generic classes work and how are they used?

Your response will be greatly appreciated!!

like image 292
Prashant Shilimkar Avatar asked Nov 29 '13 06:11

Prashant Shilimkar


People also ask

How do you check if a string is an integer?

The isdigit() method is an attribute of the string object to determine whether the string is a digit or not. This is the most known method to check if a string is an integer. This method doesn't take any parameter, instead, it returns True if the string is a number (integer) and False if it's not.

How do you fix a string that Cannot be converted to int?

The most direct solution to convert a Java string to an integer is to use the parseInt method of the Integer class: int i = Integer. parseInt(myString); parseInt converts the String to an int , and throws a NumberFormatException if the string can't be converted to an int type.

What is a class T in Java?

In java <T> means Generic class. A Generic Class is a class which can work on any type of data type or in other words we can say it is data type independent. public class Shape<T> { // T stands for "Type" private T t; public void set(T t) { this.t = t; } public T get() { return t; } }


2 Answers

You have declared a generic with no upper bound. Replacement for an unbounded generic is Object itself

This means, when the class file gets generated your Foo<T> class looks something like this

class Foo {

    private Object t;

    public Foo(Object  t) throws InstantiationException, IllegalAccessException{
       System.out.println("1. T is "+t.getClass());
       this.t = (Object)"test";
       System.out.println("2. T is "+t.getClass());
   }

   void fun(){
       System.out.println("3. T is "+t.getClass()+" t = "+t);
   }
}

This is due to the fact that, generics are only there to ensure compile time type safety . In run-time they are erased

Considering this

this.t = (Object)"test";

is a valid statement, because Object is super class of all the classes and this.t then on becomes a String

The reason for 2. T is Still class java.lang.Integer ,

  • here t is a parameter to the constructor and the parameter still points to Integer (not overwritten)
  • and the parameter takes precedence over this.t
like image 195
sanbhat Avatar answered Sep 28 '22 07:09

sanbhat


Here is your problem:

private T t;

t is a class variable here.

       System.out.println("1. T is "+t.getClass());
       this.t = (T)"test";
       System.out.println("2. T is "+t.getClass());

In above code in your sysout, the variable you are printing is 't' which is passed to method, not your class varible 't' declared above (this.t)

Class variable 't' got updated to 'String' Type, which gets printed in your "fun()" method.

like image 40
user1933888 Avatar answered Sep 28 '22 06:09

user1933888