Answers:
与上下文隔离-没有区别。在两者上t
,obj
您只能调用以下方法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
。此处的区别在于,在第一个示例中,我们指定调用者必须传递一个Object实例(任何类),并且它将返回另一个Object(任何类,不一定是同一类型)。
在第二个中,返回的类型将与定义类时给定的类型相同。
Example ex = new Example<Integer>();
在这里,我们指定类型T,这将使我们可以对类或方法施加更多约束。例如,我们可以实例化一个LinkedList<Integer>
或,LinkedList<Example>
并且我们知道,当我们调用这些方法之一时,我们将返回一个Integer或Example实例。
这里的主要目标是调用代码可以指定类将对哪种类型的对象进行操作,而不是依靠类型强制转换来强制执行此操作。
请参阅Oracle的Java泛型 *。
*更新的链接。
区别在于,使用通用方法时,我不需要强制转换,并且在执行错误时会收到编译错误:
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;
}
}
您不需要进行其他的类转换。在第一种情况下,您总是会得到一个类java.lang.Object的对象,您需要将其强制转换为您的类。在第二种情况下,T将被通用签名中定义的类替换,并且不需要类强制转换。
T是泛型类型。意味着它可以在运行时被任何合格的对象替换。您可以调用以下方法:
String response = doSomething("hello world");
要么
MyObject response = doSomething(new MyObject());
要么
Integer response = doSomething(31);
如您所见,这里有多态。
但是,如果声明它返回Object,则除非键入强制转换,否则您将无法执行此操作。
<T>
没有自动装箱吗?
在Java中可以考虑泛型而不是对象类型的理由很少: