Java泛型T vs Object

时间:2011-03-05 22:08:29

标签: java generics

我想知道以下两个方法声明之间有什么区别:

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

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

你可以/可以用一个而不是另一个吗?我在本网站的其他地方找不到这个问题。

8 个答案:

答案 0 :(得分:92)

与上下文隔离 - 没有区别。在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

答案 1 :(得分:10)

这里的区别在于,在第一个中,我们指定调用者必须传递一个Object实例(任何类),它将返回另一个Object(任何类,不一定是同一类型)。

在第二种情况下,返回的类型与定义类时给出的类型相同。

Example ex = new Example<Integer>();

这里我们指定T将是什么类型,它允许我们对类或方法强制执行更多约束。例如,我们可以实例化LinkedList<Integer>LinkedList<Example>,我们知道当我们调用其中一个方法时,我们将返回一个Integer或Example实例。

这里的主要目标是调用代码可以指定类将操作的对象类型,而不是依赖于类型转换来强制执行此操作。

请参阅Oracle的Java Generics *。

*更新链接。

答案 2 :(得分:7)

不同之处在于使用通用方法我不需要进行转换,并且在出错时遇到编译错误:

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

答案 3 :(得分:2)

在运行时,没有。但是在编译时,第二个将进行类型检查以确保参数的类型和返回值的类型匹配(或者是子类型)T解析为什么类型(第一个示例也进行类型检查但每个对象都是Object的子类型,因此将接受每种类型。

答案 4 :(得分:2)

T是通用类型。这意味着它可以在运行时由任何限定对象替换。您可以调用以下方法:

String response = doSomething("hello world");

OR

MyObject response = doSomething(new MyObject());

OR

Integer response = doSomething(31);

如您所见,这里存在多态性。

但是如果它被声明为返回Object,除非你输入cast的东西,否则你不能这样做。

答案 5 :(得分:1)

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

答案 6 :(得分:0)

在第一种情况下,它采用任何类型的参数egstring并返回一个类型foo。在第二种情况下,它采用foo类型的参数并返回类型为foo的对象。

答案 7 :(得分:0)

在Java中可以考虑泛型而不是对象类型的原因有很多:

  1. 仿制药具有灵活性和安全性。同时,使用需要类型转换的对象容易出错
  2. Java中的类型转换速度很慢 参考:[1]:https://www.infoworld.com/article/2076555/java-performance-programming--part-2--the-cost-of-casting.html