How and when the class T changes from Integer to String, and does not show an error / exception

What I did was just to find out how Generics works in Java. I wrote 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 conclusion

 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 does this change the class from Integer to String and does not show an error / exception.

And secondly, when I write t = 9; in function fun() , it shows:

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

How do common classes work and how are they used?

Your answer will be very grateful!

+7
java generics
source share
4 answers

You have specified a common with the upper bound . Replacing an unlimited generic Object itself

This means that when you create the class file, 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 exist only to ensure the safety of time . At runtime they are erased

Considering this

 this.t = (Object)"test"; 

is a valid operator because Object is the superclass of all classes and this.t , then on becomes a String

Reason 2. T is Still class java.lang.Integer ,

  • here t is the parameter for the constructor, and the parameter still points to Integer (not overwritten)
  • and this parameter takes precedence over this.t
+4
source share

Here is your problem:

 private T t; 

t is a class variable.

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

In the above code of your sysout, the variable you print is "t", which is passed to the method, and not your varible 't' class declared above (this.t)

The class variable 't' has been updated to type "String", which is printed in your "fun ()" method.

+1
source share

Yes. Your declaration Foo o = new Foo<Integer>(new Integer(5)); should be Foo<Integer> o = new Foo<Integer>(new Integer(5)); (or if you use Java 7 and above the diamond operator), like this Foo<Integer> o = new Foo<>(5)); . The original fun() is called based on Foo (equivalent to Foo<Object> after type erasure). That means it works like

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

Also your constructor should be

 this.t = (T) t; 

And NOT this

 this.t = (T)"test"; // Which is why you're getting a String! 
0
source share

'this.t = (T) "test"; this is not true. you cannot change the type of a class. first determined. in class T must be integer, because first you specified the type as a whole reference to examples of generalizations

when you see, replace all "T" with "Integer". good hack

0
source share

All Articles