我想知道使用?在java泛型中。通过研究占位符T和通配符? ,我想知道?,经历了几个网站/页面和书籍,但没有理解它。所以我创建了下面的课来研究差异。
import java.util.List;
public class Generics2 {
public <T> void method1(List<T> list){
System.out.println(list);
}
public <T extends Number> void method2(List<T> list){
System.out.println(list);
}
/*public <T super Integer> void method3(List<T> list){
}*///super does not work.
public void method4(List<?> list){
System.out.println(list);
}
public void method5(List<? extends Number> list){
System.out.println(list);
}
public void method6(List<? super Integer> list){
System.out.println(list);
}
public <T> void copy1(List<T> list1, List<T> list2){
//copy elements from list1 to list2
}//It does not span well with copy of one type of elements from list1 to other type elements in list2, where the list elements
//between the two are not same but are related through inheritance.
public <T1,T2> void copy2(List<T1> list1,List<T2> list2){
//copy elements from list1 to list2, right now we do not bother about the exceptions or errors that might generate.
}//Our intention here is not to copy elements with relation between T1 and T2. We intend to explore the differences on T and ?
public void copy3(List<?> list1,List<?> list2){
//copy elements from list1 to list2, right now we do not bother about the exceptions or errors that might generate.
}//Our intention here is not to copy elements with relation between T1 and T2. We intend to explore the differences on T
public <T1 extends Object, T2 extends Object> void copy4(List<T1> list1, List<T2> list2){
//copy elements from list1 to list2
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
在一个案例中,我的班级可能会遗漏几个场景,所以我写的内容不完整,在这种情况下,任何人都可以帮助我实现更多场景。或者我找到了?作为冗余,除了它提供的功能,如在方法签名中使用超级关键字和较小字符以及返回类型。
修改 基本上我的问题是要了解背后的原因,介绍的目的?通配符可以在任何地方替换它的通配符。这不是如何使用的问题?或T类型。当然,知道它的用法会提供一些答案。 例如,我推断的事情:
还有吗?
答案 0 :(得分:3)
?
表示:类型未指定。含义:如果您的代码中没有其他原因要求您拥有&#34;命名&#34;类型参数;你可以/应该使用?
来表达这一点。
实际上,我问过一段时间了,所以你可能会发现这里的答案很有帮助:Java generics: wildcard<?> vs type parameter<E>?
答案 1 :(得分:2)
当列表(或集合)属于未知类型时,使用无界通配符。
当你想要插入值到列表时,你永远不应该使用它(因为你可以插入的唯一值是null
)。
在您获取某些数据结构的信息时使用它,例如打印其内容,当您不知道它的类型时可能包含。例如:
public static void printList(List<?> list) {
for (Object elem: list)
System.out.print(elem + " ");
System.out.println();
}
答案 2 :(得分:1)
有人为这个问题写了一个很好的答案here。问号基本上意味着&#34;任何类型&#34;,但在使用接口或抽象类时它非常有用。例如,
NSArray *viewContrlls=[[self navigationController] viewControllers];
for( int i=0;i<[ viewContrlls count];i++){
id obj=[viewContrlls objectAtIndex:i];
if([obj isKindOfClass:[A class]]){
// A is your class where to popback
[[self navigationController] popToViewController:obj animated:YES];
return;
}
}
这很有用,因为您仍然可以进行类型检查,以确保放入列表中的任何内容都是MyClass的子类。如果您需要使用抽象类中的特定方法或字段,则无论具体实现如何,您都可以为所有子类使用它。有关更真实的示例,我将其用于URL路由:
List<? extends MyAbstract> myClasses = new ArrayList<? extends MyAbstract>();