Java generics T vs Object

JavaGenerics

Java Problem Overview


I was wondering what is the difference between the following two method declarations:

public Object doSomething(Object obj) {....}

public <T> T doSomething(T t) {....}

Is there something you can/would do with one but not the other? I could not find this question elsewhere on this site.

Java Solutions


Solution 1 - Java

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 returns Foo. If it returns Bar, you'll have a ClassCastException, at runtime.

Solution 2 - Java

The difference here is that in the first, we specify that the caller must pass an Object instance (any class), and it will get back another Object (any class, not necessarily of the same type).

In the second, the type returned will be the same type as that given when the class was defined.

Example ex = new Example<Integer>();

Here we specify what type T will be which allows us to enforce more constraints on a class or method. For example we can instantiate a LinkedList<Integer> or LinkedList<Example> and we know that when we call one of these methods, we'll get back an Integer or Example instance.

The main goal here is that the calling code can specify what type of objects a class will operate upon, instead of relying on type-casting to enforce this.

See Java Generics* from Oracle.

*Updated Link.

Solution 3 - Java

The difference is that with generic methods I don't need to cast and I get a compilation error when I do wrong:

public class App {

	public static void main(String[] args) {

		String s = process("vv");
		String b = process(new Object()); // Compilation error
	}
	
	public static <T> T process(T val) {
	
		return val;
	}
}

Using object I always need to cast and I don't get any errors when I do wrong:

public class App {

	public static void main(String[] args) {

		String s = (String)process("vv");
		String b = (String)process(new Object());
	}
	
	public static Object process(Object val) {
	
		return val;
	}
}

Solution 4 - Java

You don't need to do additional class casting. In first case you will always get an object of class java.lang.Object which you will need to cast to your class. In second case T will be replaced with the class defined in generic signature and no class casting will be needed.

Solution 5 - Java

At runtime, nothing. But at compile time the second will do type checking to make sure the type of the parameter and the type of the return value match (or are subtypes of) whatever type T resolves to (the first example also does type checking but every object is a subtype of Object so every type will be accepted).

Solution 6 - Java

T is a generic type. Meaning it can be substituted by any qualifying object at runtime. You may invoke such a method as follows:

String response = doSomething("hello world");

OR

MyObject response = doSomething(new MyObject());

OR

Integer response = doSomething(31);

As you can see, there is polymorphism here.

But if it is declared to return Object, you can't do this unless you type cast things.

Solution 7 - Java

in the first case it takes a parameter of any type e.g.string and return a type foo. In the second case it takes a parameter of type foo and returns an object of type foo.

Solution 8 - Java

There are few reasons that you can consider Generics over Object type in Java:

  1. Generics is flexible and safe. At the same time, working with Object that requires type-casting is error-prone
  2. Type Casting in Java is slow ref : [1]: https://www.infoworld.com/article/2076555/java-performance-programming--part-2--the-cost-of-casting.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAbidiView Question on Stackoverflow
Solution 1 - JavaBozhoView Answer on Stackoverflow
Solution 2 - JavaAdamView Answer on Stackoverflow
Solution 3 - Javauser1883212View Answer on Stackoverflow
Solution 4 - JavaAndrey AdamovichView Answer on Stackoverflow
Solution 5 - JavaJonathanView Answer on Stackoverflow
Solution 6 - JavaadarshrView Answer on Stackoverflow
Solution 7 - JavafastcodejavaView Answer on Stackoverflow
Solution 8 - JavabiddutView Answer on Stackoverflow