Java泛型T与对象


127

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

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

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

有什么可以/可以做的,而不是另一种?我在本网站的其他地方找不到这个问题。

Answers:


112

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

14

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

在第二个中,返回的类型将与定义类时给定的类型相同。

Example ex = new Example<Integer>();

在这里,我们指定类型T,这将使我们可以对类或方法施加更多约束。例如,我们可以实例化一个LinkedList<Integer>或,LinkedList<Example>并且我们知道,当我们调用这些方法之一时,我们将返回一个Integer或Example实例。

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

请参阅Oracle的Java泛型 *。

*更新的链接。


13

区别在于,使用通用方法时,我不需要强制转换,并且在执行错误时会收到编译错误:

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
约翰·洛

2

您不需要进行其他的类转换。在第一种情况下,您总是会得到一个类java.lang.Object的对象,您需要将其强制转换为您的类。在第二种情况下,T将被通用签名中定义的类替换,并且不需要类强制转换。


2

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


2

T是泛型类型。意味着它可以在运行时被任何合格的对象替换。您可以调用以下方法:

String response = doSomething("hello world");

要么

MyObject response = doSomething(new MyObject());

要么

Integer response = doSomething(31);

如您所见,这里有多态。

但是,如果声明它返回Object,则除非键入强制转换,否则您将无法执行此操作。


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

0

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.