BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #65824同步于 2021/8/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

请问List<? extends Number> 和 List<T extends Number>语法上

yb7858833
2021/8/15镜像同步10 回复
import java.util.*; public class Example { static void doesntCompile(Map<Integer, List<? extends Number>> map) {} static <T extends Number> void compiles(Map<Integer, List<T>> map) {} static void function(List<? extends Number> outer) { doesntCompile(new HashMap<Integer, List<Integer>>()); compiles(new HashMap<Integer, List<Integer>>()); } } //报错 Example.java:9: error: incompatible types: HashMap<Integer,List<Integer>> cannot be converted to Map<Integer,List<? extends Number>> doesntCompile(new HashMap<Integer, List<Integer>>()); ———————————————————————————————————— public class Example { // 可以正常编译 static void doesntCompile(Map<Integer, ? extends List<? extends Number>> map) {} static <T extends Number> void compiles(Map<Integer, List<T>> map) {} public static void main(String[] args) { doesntCompile(new HashMap<Integer, List<Integer>>()); compiles(new HashMap<Integer, List<Integer>>()); } } 请问为什么? extends List<? extends Number>和List<T extends number>的效果是一样的呢?谢谢大家!
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
yb7858833机器人#1 · 2021/8/15
问题应该是出在map上 class Example { // 可以正常编译 static <T extends Number> void doesntCompile(List<? extends Number> list) {} static <T extends Number> void compiles(List<T> list) {} public static void main(String[] args) { doesntCompile(new ArrayList<Integer>()); compiles(new ArrayList<Integer>()); } } 这里是不会报错的 所以是不是Map类型声明的时候要这样写呢?这又是为啥呢orz
nuanyangyang机器人#2 · 2021/8/15
就像白马不是马一样,ArrayList<Integer>也不是List<Integer> 了解一下covariant contravariant invariant这几个概念
yb7858833机器人#3 · 2021/8/15
感谢暖神 我去学习一下 【 在 nuanyangyang 的大作中提到: 】 : 就像白马不是马一样,ArrayList<Integer>也不是List<Integer> : 了解一下covariant contravariant invariant这几个概念
yb7858833机器人#4 · 2021/8/15
【 在 nuanyangyang 的大作中提到: 】 : 就像白马不是马一样,ArrayList<Integer>也不是List<Integer> : 了解一下covariant contravariant invariant这几个概念 请问暖神为什么这样不会被泛型擦除呢? class Father { } class Daughter extends Father{} class Son extends Father{} class Test { public <T extends Father> void test(T t) { if (t instanceof Daughter) { System.out.println("daughter"); } if (t instanceof Son) { System.out.println("son"); } } @org.junit.jupiter.api.Test public void test() { test(new Daughter()); } } 感谢![ema4]
TroyAchilles机器人#5 · 2021/8/15
擦除过后变成test(Father t),传入Daughter类,所以符合第一个if,输出daughter吧?
yb7858833机器人#6 · 2021/8/15
第二个没有输出呢 【 在 TroyAchilles 的大作中提到: 】 : 擦除过后变成test(Father t),传入Daughter类,所以符合第一个if,输出daughter吧?
TroyAchilles机器人#7 · 2021/8/15
为什么第二个会输出?你传入的是daughter对象啊 【 在 yb7858833 的大作中提到: 】 : 第二个没有输出呢
yb7858833机器人#8 · 2021/8/15
我的意思就是为什么这个传入的daughter可以被识别出来真正指向的是Daughter对象 而不是被擦除成Father呀[ema41] 【 在 TroyAchilles 的大作中提到: 】 : 为什么第二个会输出?你传入的是daughter对象啊
TroyAchilles机器人#9 · 2021/8/15
会被擦除的是泛型方法或者泛型变量,比如这里的test方法就会被擦除成test(father t),相当于你把一个daughter对象传入这个函数,也就是父类引用指向子类对象。而daughter并不是一个泛型变量,所以不会擦除它 【 在 yb7858833 的大作中提到: 】 : 我的意思就是为什么这个传入的daughter可以被识别出来真正指向的是Daughter对象 而不是被擦除成Father呀[ema41]