无限制的通配符List

BaronZ 2013-01-17 04:09:13
最近在effective java中看到无限制通配符,没理解,特发此帖,向高手讨教一下:
比如
void test(List<?> list){}

书中说的是,不能把null之外的任何值放入List<?>中
1.这是什么意思?只能放null值?
2.我试着写以下代码,也没出错,是我理解错了?
List list = new ArrayList(); list.add(1); swap(list);

3.这么写的作用是什么?
...全文
3534 53 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq840727854 2015-04-03
  • 打赏
  • 举报
回复
List == List<Object> 比如 我现在 需要传个 参数 是 List<String> 有个 方法 void (List<Object> objList) 这个 是不能接受我 List<String>这个参数的 因为List<Object> 不是 List<String>的父类 而List<?> 是任何List<> 类型 的父类 List<?> 是为了 接收参数, 并且可以获取参数里的值 进行操作。 List<?> get出来的 是Object对象, 但是List<?> 只能加null 因为 无法 确定 ?具体是什么对象, 有可能是String,有可能是Integer 所以只能加null。 取的 话 不管你?是String 还是Integer 都是 Object 所以 可以取
cnsdlyl 2015-04-02
  • 打赏
  • 举报
回复
#18说的比较好,接受泛型类型不同的形参,同时,只能添加null的意义在于,形参接受后不能因添加元素修改了原来的泛型类型。算所是医用约束吧
abc123698745cba 2015-04-02
  • 打赏
  • 举报
回复
个人觉得List <?> 与List 差别在于省去了后来的 类型对象强制转换 这一步
Sandm_ 2014-11-17
  • 打赏
  • 举报
回复
引用 25 楼 BaronZ 的回复:
[quote=引用 24 楼 nmyangym 的回复:] 引用 18 楼 Inhibitory 的回复: Java code?123456789101112131415161718192021222324252627282930313233import java.util.LinkedList;import java.util.List; public class Hello { public static void main(String[] ……
官方给出了下面的例子,我也插了代码进去。 我想官方代码的意思就List<?>相当于List<? extends Object> 而List<Object>已经定了只能传入Object. 但是,List<?>又和List<E>有什么区别呢?写入的区别?

//Consider the following method, printList:

public static void printList(List<Object> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}
//The goal of printList is to print a list of any type, but it fails to achieve that goal — it prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>. To write a generic printList method, use List<?>:

public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}
//Because for any concrete type A, List<A> is a subtype of List<?>, you can use printList to print a list of any type:

List<Integer> li = Arrays.asList(1, 2, 3);
List<String>  ls = Arrays.asList("one", "two", "three");
printList(li);
printList(ls);//这样的话,如果调用List<Object>那个方法确实不行,但是为什么不用List<E>呢?
//----------------我的代码
public static <E> void printList(List<E> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}
//这样的话,上面的结果也是可以打的



[/quote]List<?> 可以接收不定类型返回值,并且输出,例如:
public List<?> getRecListByDate(String loginName,Date dateStart,Date dateEnd,String Type) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("select ");
		buffer.append(Type);
		buffer.append(" from tb_record where date >= :p1 and date <= :p2 and username = :p3 order by id");
		Query query =  createSqlQuery(buffer.toString(), new Parameter(dateStart,dateEnd,loginName));
                return query.list();
//接收
List<?> records1 = new ArrayList<Double>();
 records1 = getRecListByDate(token.getUsername(), formatDate.StringToDate(startDate), formatDate.StringToDate(endDate),Type);
前面的查询结果类型并不确定,接收是类型也是不确定的,这时候用List<?>可以接收到
yuhouqingchen_2648 2014-06-05
  • 打赏
  • 举报
回复
引用 47 楼 dracularking 的回复:
说错了,不过?代表未知类型 而 List<E> listUnknown1 = new ArrayList<Integer>(); 这里的E代表的恰恰是一个确定但未知的类型,所以编译不通过(因为E未必是Integer)
建议楼主多看看这个人的回答,会准确,很到位
擦肩的阳光 2014-04-08
  • 打赏
  • 举报
回复
List<?>:具有某种特定类型的非原生List,只是我们不知道那种类型是什么。 thinking in java P396..
nmyangym 2013-01-25
  • 打赏
  • 举报
回复
"那又和List<E>有什么区别?" 我最近在学习这个泛型,有点体会,不知对否,不对的话,请指正! 1 ?这个通配符代表已知类型,他与 ? extends someClass, someClass是一样的,出现于使用某个已 经定义的泛型类,泛型方法或泛型接口中。 2 E 及E extends someClass 出现于定义泛型类,泛型接口,泛型方法中。 3 List<?> 和 List<E>是有本质的区别的。List<?>, 是在使用泛型类List,这个不管具体里面是什么, 但已经是一个明确的,可被赋值的类型了。可以给它赋值。 比如,List<?> listUnknown = null; listUnknown = new ArrayList<Integer>(); 或listUnknown = new LinkedList<String>(); 等等。 但List<E> 它还不是一个已知的类,还不能被赋值。只能出现在定义泛型的方法中。(List已经是 被定义成泛型类了).如33楼,后面的代码,需加上<E> 类型声明。
dracularking 2013-01-25
  • 打赏
  • 举报
回复
说错了,不过?代表未知类型 而 List<E> listUnknown1 = new ArrayList<Integer>(); 这里的E代表的恰恰是一个确定但未知的类型,所以编译不通过(因为E未必是Integer)
dracularking 2013-01-25
  • 打赏
  • 举报
回复
引用 45 楼 nmyangym 的回复:
"那又和List<E>有什么区别?" 我最近在学习这个泛型,有点体会,不知对否,不对的话,请指正! 1 ?这个通配符代表已知类型,他与 ? extends someClass, someClass是一样的,出现于使用某个已 经定义的泛型类,泛型方法或泛型接口中。 2 E 及E extends someClass 出现于定义泛型类,泛型接口,泛……
33楼的35楼有补充 public static <E> String classify(List<E> lst) { return "List"; }
为啥呢 2013-01-24
  • 打赏
  • 举报
回复
引用 39 楼 BaronZ 的回复:
引用 35 楼 raistlic 的回复:1.第二个应该编译不了吧 2.区别很细微…… 首先第一个 List<?> 是只读的,如果你试图在方法内调用 lst.add(),只要不是 add(null) 都不能通过编译; 第二个可以用强转的方式add(),虽然可能会破坏类型安全。 然后第二个方法是泛型方法,你在调用的时候可以指定具体类型,这个具体类型可以作为返回类……
我只是打个比方,范型是对元素的类型限制,如果你在编译前没有确定类型,你就应该用<E>通过接收传入类型来确定需要限定的类型,如传入String,他就兼容String,是动态的类型限定; 如果你在编译前能确定类型就写<Type>,这样必须完全兼容Type类型才能传入,也就是静态的类型限定,<?>就是指定一个未知的Type,因为必须完全兼容才能传入,而未知类型与任何类型都不能完全兼容,所以只能匹配null值。
BaronZ 2013-01-24
  • 打赏
  • 举报
回复
引用 35 楼 raistlic 的回复:
1.第二个应该编译不了吧 2.区别很细微…… 首先第一个 List<?> 是只读的,如果你试图在方法内调用 lst.add(),只要不是 add(null) 都不能通过编译; 第二个可以用强转的方式add(),虽然可能会破坏类型安全。 然后第二个方法是泛型方法,你在调用的时候可以指定具体类型,这个具体类型可以作为返回类型使用:
1.是的,我大概写了个例子,没太严谨,要在类或者方法那里先声明。 2.看明白你意思了。即用?不可以做为具体类型返回?但是感觉有点奇怪。这么做的用途是什么? 即声明List<?>,让你来用的话,你会用在什么场景?
引用 37 楼 xodbc 的回复:
引用 34 楼 BaronZ 的回复: 或者能不能通俗地说一下上面两个例子的区别? ?和String一样是个类型常量,无法改变,必须和完全相同的类型才能匹配,E是一个类型变量,运行时给这个变量赋值类型后他就指代那种类型。
没太看明白
beowulf2005 2013-01-24
  • 打赏
  • 举报
回复
引用 28 楼 xodbc 的回复:
泛型是jdk1.5加的,本着向下兼容的原则,不指定泛型时类型与老版本相同,就是Object。 <?>意思是未知类型,就是不设上下限 <? extend Object>意思是继承于Object的未知类型 <? super Object>意思是Object的祖先类型 后面还可以用&接口名序列指定接口 <E>可以应用以上的格式,对于类,可以在类声明时指定泛型类……
有这种用法????!!
dracularking 2013-01-24
  • 打赏
  • 举报
回复
可以用在这种场合
void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}
但又可以被E代替,貌似唯一性职能没有体现出来
JPF1024 2013-01-24
  • 打赏
  • 举报
回复
引用 12 楼 suciver 的回复:
List<E>或List<?>如果只是单纯的定义的话是无区别的。但是如果你要引用的话就有区别了 List<E>表示说list中可以任意E类型的对象这个E可以被你在声明中引用到 例如在方法中 public <E> void a(List<E> list){ E e=list.get(0); 后面再对着e对象可以做各种操作 } 但是如果是?的 就不能在引用了 ……
这个说的有道理,加泛型是为了约束放入里面的值,也方便引用,不过还真没用过这个List <?>,顶多,List<Object>.
arenc 2013-01-24
  • 打赏
  • 举报
回复
不明白List<?>只能加null,什么场景会用到?
为啥呢 2013-01-23
  • 打赏
  • 举报
回复
引用 34 楼 BaronZ 的回复:
或者能不能通俗地说一下上面两个例子的区别?
?和String一样是个类型常量,无法改变,必须和完全相同的类型才能匹配,E是一个类型变量,运行时给这个变量赋值类型后他就指代那种类型。
raistlic 2013-01-23
  • 打赏
  • 举报
回复
引用 35 楼 raistlic 的回复:
引用 34 楼 BaronZ 的回复:或者能不能通俗地说一下上面两个例子的区别?

public static <E> E classify(List<E> lst){
        return "List";
}
 
// user code:
String s = ClassName.<String>classify(Arrays.asList("1","2","3"));
Integer i = ClassName.<Integer>classify(Arrays.asList(1, 2, 3));
例子中的 return 语句错了,不过意思你能明白就行了。
raistlic 2013-01-23
  • 打赏
  • 举报
回复
引用 34 楼 BaronZ 的回复:
或者能不能通俗地说一下上面两个例子的区别?
第二个应该编译不了吧

// 应该加上泛型声明
public static <E> String classify(List<E> lst){
        return "List";
}
区别很细微…… 首先第一个 List<?> 是只读的,如果你试图在方法内调用 lst.add(),只要不是 add(null) 都不能通过编译; 第二个可以用强转的方式add(),虽然可能会破坏类型安全。 然后第二个方法是泛型方法,你在调用的时候可以指定具体类型,这个具体类型可以作为返回类型使用:

public static <E> E classify(List<E> lst){
        return "List";
}

// user code:
String s = ClassName.<String>classify(Arrays.asList("1","2","3"));
Integer i = ClassName.<Integer>classify(Arrays.asList(1, 2, 3));
BaronZ 2013-01-23
  • 打赏
  • 举报
回复
或者能不能通俗地说一下上面两个例子的区别?
BaronZ 2013-01-23
  • 打赏
  • 举报
回复
引用 27 楼 dracularking 的回复:
25楼例子不足以说明其区别 ? 就代表任意类型,unknown type E 是 formal type parameter 确定类型只是未知 就是这样的区别我觉得
引用 28 楼 xodbc 的回复:
泛型是jdk1.5加的,本着向下兼容的原则,不指定泛型时类型与老版本相同,就是Object。 <?>意思是未知类型,就是不设上下限 <? extend Object>意思是继承于Object的未知类型 <? super Object>意思是Object的祖先类型 后面还可以用&接口名序列指定接口 <E>可以应用以上的格式,对于类,可以在类声明时指定泛型类型,对于方法可以通过参数传……
引用 30 楼 raistlic 的回复:
引用 29 楼 raistlic 的回复: 讨论不如直接查书 <Effective Java> 第二版 P109~146,多读两遍。 这个建议适用于任何发Java泛型疑问贴的同学,在论坛里见了不少对泛型有疑问的帖子,没有一个问题超出书里描述的范围。
那你们觉得下面给出的两个方法有区别吗?

public static String classify(List<?> lst){
		return "List";
}
public static String classify(List<E> lst){
		return "List";
}

加载更多回复(31)

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧