Java泛型T vs Object

Abi*_*idi 116 java generics

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

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

public <T> T doSomething(T t) {....}
Run Code Online (Sandbox Code Playgroud)

有什么东西可以/可以用一个而不是另一个吗?我在本网站的其他地方找不到这个问题.

Boz*_*zho 102

与上下文隔离 - 没有区别.在两者上t,obj您只能调用方法Object.

但是有了上下文 - 如果你有一个泛型类:

MyClass<Foo> my = new MyClass<Foo>();
Foo foo = new Foo();
Run Code Online (Sandbox Code Playgroud)

然后:

Foo newFoo = my.doSomething(foo);
Run Code Online (Sandbox Code Playgroud)

与对象相同的代码

Foo newFoo = (Foo) my.doSomething(foo);
Run Code Online (Sandbox Code Playgroud)

两个优点:

  • 不需要强制转换(编译器会隐藏此信息)
  • 编译时间安全有效.如果使用该Object版本,您将无法确定该方法始终返回Foo.如果它返回Bar,你将ClassCastException在运行时有一个.


Ada*_*dam 12

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

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

Example ex = new Example<Integer>();
Run Code Online (Sandbox Code Playgroud)

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

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

请参阅Oracle的Java Generics*.

*更新链接.


use*_*212 10

不同的是,使用泛型方法我不需要强制转换,当我做错时,我得到一个编译错误:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用对象我总是需要施放,当我做错时我没有得到任何错误:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)