Java generics T vs Object
Isolated from context - no difference. On both t
and obj
you can invoke only the methods of Object
.
But with context - if you have a generic class:
MyClass<Foo> my = new MyClass<Foo>();
Foo foo = new Foo();
Then:
Foo newFoo = my.doSomething(foo);
Same code with object
Foo newFoo = (Foo) my.doSomething(foo);
Two advantages:
- no need of casting (the compiler hides this from you)
- compile time safety that works. If the
Object
version is used, you won't be sure that the method always returnsFoo
. If it returnsBar
, you'll have aClassCastException
, at runtime.
What is the difference between type T and Object?
At runtime, there is no difference: Java generics are implemented through Type Erasure, so the same class is used in all implementations.
At compile time, however, the difference is enormous, because it lets you avoid casting every time that you use an object, making you code look a lot cleaner.
Consider this example:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (Integer n : list) {
System.out.println(n+5);
}
This compiles and runs well, and it also easy to read. If you wanted to use List<Object>
instead, the code would not look as clean:
List<Object> list = new ArrayList<Object>();
list.add(1);
list.add(2);
list.add(3);
for (Object o : list) {
// Now an explicit cast is required
Integer n = (Integer)o;
System.out.println(n+5);
}
Internally, though, the two code snippets use the same exact implementation for their list
object.
What is the difference between ? and Object in Java generics?
An instance of HashMap<String, String>
matches Map<String, ?>
but not Map<String, Object>
. Say you want to write a method that accepts maps from String
s to anything: If you would write
public void foobar(Map<String, Object> ms) {
...
}
you can't supply a HashMap<String, String>
. If you write
public void foobar(Map<String, ?> ms) {
...
}
it works!
A thing sometimes misunderstood in Java's generics is that List<String>
is not a subtype of List<Object>
. (But String[]
is in fact a subtype of Object[]
, that's one of the reasons why generics and arrays don't mix well. (arrays in Java are covariant, generics are not, they are invariant)).
Sample:
If you'd like to write a method that accepts List
s of InputStream
s and subtypes of InputStream
, you'd write
public void foobar(List<? extends InputStream> ms) {
...
}
By the way: Joshua Bloch's Effective Java is an excellent resource when you'd like to understand the not so simple things in Java. (Your question above is also covered very well in the book.)
Java generics, Unbound wildcards ? vs Object
There are two separate issues here. A List<Object>
can in fact take any object as you say. A List<Number>
can take at least Number
objects, or of course any subclasses, like Integer
.
However a method like this:
public void print(List<Number> list);
will actually only take a List
which is exactly List<Number>
. It will not take any list which is declared List<Integer>
.
So the difference is List<?>
will take any List with whatever declaration, but List<Object>
will only take something that was declared as List<Object>
, nothing else.
The last quote simply states, that List<?>
is a list for which you literally don't know what type its items are. Because of that, you can not add anything to it other than null
.
Generics vs Object vs Comparable
The conceptual thing to know about: Java arrays are covariant!
That means: you can write a method like
public void sort(Object[] data)
and use that with an array of Objects, but also with an Integer[], String[] whatever.
That has the advantage that you can write code that works "generically" for all kinds of different input.
But the problem with that is that it can lead to surprises at runtime, for example when your array contains Integer and String objects.
Thus the Java language folks decides to make generics, and more specifically collections of Generics invariant. Therefore you can't do
public void sort(List<Number> numbers)
and call that with some List<Integer>
.
In that sense: when using arrays, then there isn't much sense in using generics. But: when using generics, you would (most of the time) prefer using collections over arrays! And then, you have to really know about the conceptual differences.
Dart. What the difference between using generic T and Object?
Generics allows to avoid many declarations when only types change between several classes. In your example the TestObject
class can be removed and replaced with TestGeneric<Object>
everywhere TestObject
appears.
Your expected output for (new TestObject()).Pass('string').runtimeType
is not correct. runtimeType
returns the type of the object. Here it is 'string'
that is returned and so 'string'.runtimeType
is String
.
To know the return type of a method you have to use mirrors at runtime or analyzer at build time.
What is the difference between 'E', 'T', and '?' for Java generics?
Well there's no difference between the first two - they're just using different names for the type parameter (E
or T
).
The third isn't a valid declaration - ?
is used as a wildcard which is used when providing a type argument, e.g. List<?> foo = ...
means that foo
refers to a list of some type, but we don't know what.
All of this is generics, which is a pretty huge topic. You may wish to learn about it through the following resources, although there are more available of course:
- Java Tutorial on Generics
- Language guide to generics
- Generics in the Java programming language
- Angelika Langer's Java Generics FAQ (massive and comprehensive; more for reference though)
What is the difference between T and T extends Object in java?
There's no difference. <T>
and <T extends Object>
are equivalent.
Why are generics needed when we can do casting to Object class?
I can make a list in the "pre-generic" way and do something terrible like this. The result is I can't know the type of the object I get from the list without resorting to reflection.
List myList = new ArrayList();
myList.add(new Integer(1));
myList.add(new Cat());
Object whatIsThis = myList.get(1);
With generics, I can say
List<Cat> myList = new ArrayList();
myList.add(new Cat());
myList.add(new Integer(1)); // compile time error
myList.add(new Dog()); // compile time error
Cat whatIsThis = myList.get(1); // I *know* this must be a Cat
Related Topics
Why Have One Jvm Per Application
What Is the Most Recommended Way to Store Time in Postgresql Using Java
How to Add Test Coverage to a Private Constructor
Sessiontimeout: Web.Xml VS Session.Maxinactiveinterval()
Java Try/Catch/Finally Best Practices While Acquiring/Closing Resources
Hashmap Implementation in Java. How Does the Bucket Index Calculation Work
Create Java Runtime Image on One Platform for Another Using Jlink
Does Stream.Foreach Respect the Encounter Order of Sequential Streams
Converting Date-String to a Different Format
How to Enable Anti Aliasing in Arbitrary Java Apps
How Does Java Object Casting Work Behind the Scene
What Is the Shortest Way to Pretty Print a Org.W3C.Dom.Document to Stdout
Find Files in a Folder Using Java
Why Is System.Arraycopy Native in Java
Change Database Schema Used by Spring Boot