Abidi
Abidi

Reputation: 7996

Java generics T vs Object

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.

Upvotes: 168

Views: 111533

Answers (9)

Ersan Aydogdu
Ersan Aydogdu

Reputation: 1

Like in the example below, you can use generics more safely. Type T must extend "BaseClass", other classes will generate compilation error.

public class MyClass<T extends BaseClass> {
    List<T> list;
}

Upvotes: 0

biddut
biddut

Reputation: 351

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

Upvotes: 0

user1883212
user1883212

Reputation: 7859

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;
    }
}

Upvotes: 18

Adam
Adam

Reputation: 5141

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.

Upvotes: 18

Bozho
Bozho

Reputation: 597106

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.

Upvotes: 143

fastcodejava
fastcodejava

Reputation: 41097

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.

Upvotes: 0

adarshr
adarshr

Reputation: 62593

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.

Upvotes: 2

Jonathan
Jonathan

Reputation: 3253

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).

Upvotes: 2

Andrey Adamovich
Andrey Adamovich

Reputation: 20663

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.

Upvotes: 3

Related Questions