Java泛型 T 与 Object 的区别

164

我想知道以下两种方法声明之间的区别:

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

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

你能用其中一个做些什么,而另一个却不能吗?我在这个网站上没有找到这个问题的答案。

8个回答

143

与上下文隔离 - 没有区别。在 tobj 上,您只能调用Object的方法。

但是如果有上下文 - 如果您有一个通用类:

MyClass<Foo> my = new MyClass<Foo>();
Foo foo = new Foo();

然后:

Foo newFoo = my.doSomething(foo);

同样的代码,使用对象

Foo newFoo = (Foo) my.doSomething(foo);

两个优点:

  • 无需强制转换(编译器会为您隐藏此过程)
  • 编译时安全性。如果使用Object版本,则无法确定方法是否始终返回Foo。如果它返回Bar,则在运行时会出现ClassCastException

18
这里的区别在于,第一个是指定调用者必须传递一个对象实例(任何类),并将返回另一个对象实例(任何类,不一定是相同类型)。
而在第二个中,返回的类型将与定义类时给定的类型相同。
Example ex = new Example<Integer>();

在这里,我们指定T的类型,这使得我们能够对类或方法强制执行更多的约束。例如,我们可以实例化一个LinkedList<Integer>LinkedList<Example>,并且我们知道当我们调用这些方法时,我们将会得到一个Integer或Example实例。
这里的主要目标是调用代码可以指定类将操作哪种类型的对象,而不是依赖于类型转换来实现这一点。
请参见Oracle的Java Generics*。
*更新链接。

18

区别在于使用泛型方法时,我不需要进行强制类型转换,而且如果我操作不当会得到编译错误:

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

使用对象时,我总是需要进行转换,但如果我操作不当,则不会收到任何错误提示:

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

只是想提一下,从Android 6开始,您不再需要强制转换对象。 - John Lord

3

无需进行额外的类转换。在第一种情况下,您将始终得到一个java.lang.Object类的对象,您需要将其强制转换为您的类。在第二种情况下,T将被替换为泛型签名中定义的类,不需要进行类转换。


2

在运行时,没有任何区别。但是在编译时,第二个示例将进行类型检查,以确保参数的类型和返回值的类型匹配(或是T类型的子类型)。而第一个示例也进行了类型检查,但由于每个对象都是Object的子类型,因此每种类型都会被接受。


2

T是一种通用类型,意味着它可以在运行时由任何符合条件的对象进行替换。您可以按照以下方式调用此类方法:

String response = doSomething("你好世界");

或者

MyObject response = doSomething(new MyObject());

或者

Integer response = doSomething(31);

正如您所看到的,这里存在多态性。

但如果声明返回Object,则除非您对事物进行类型转换,否则无法执行此操作。


我们可以说使用 <T> 就没有自动装箱吗? - SMUsamaShah

0

在第一种情况下,它接受任何类型的参数,例如字符串,并返回类型为foo的结果。在第二种情况下,它接受类型为foo的参数并返回类型为foo的对象。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接