首页   注册   登录
ONLINE

wqlin

V2EX 第 165824 号会员,加入于 2016-04-01 09:35:13 +08:00
今日活跃度排名 2579
wqlin 最近回复了
231 天前
回复了 digitalwater 创建的主题 职场话题 帝都年薪 50W 还是肉翻美帝读 PhD
@digitalwater 😃谢谢楼主,楼主强啊,两年 50w。方便透露下在哪个公司或者加个 wc 聊一下?
231 天前
回复了 digitalwater 创建的主题 职场话题 帝都年薪 50W 还是肉翻美帝读 PhD
楼主申请到了 phd ?能分享下流程和经历吗
302 天前
回复了 kaxi 创建的主题 程序员 在微服务架构中是否可用 redis 代替 etcd?
@wqlin #9 服务的注册和发现,etcd 利用了其租约特性。这句话怎么理解?租约不是加快读性能吗
302 天前
回复了 kaxi 创建的主题 程序员 在微服务架构中是否可用 redis 代替 etcd?
服务注册和发现 自身要保证高可用、数据不丢吧。这些 redis 做不了保证,etcd 可以保证。
不过既然考虑 etcd,为啥不考虑 consul,直接支持服务注册和发现
@lhx2008 我到没怎么用过 Collections 中的 get 函数,只是表达下 T 和 ? super T 区别。不过为啥是第一个参数而不是第二个参数?
@lhx2008 有区别啊。比如说 T 是 Number,你的 copy 只能将 List<Integer> 拷贝到 List<Number> 中。那如果我想将
List<Integer> 拷贝到 List<Object> 就要用第一种写法了
@lhx2008 #12 第二个参数 extends T 是不能调用 add 方法的,会报编译错误的。
比如申明了
```
List<? extends Number> myNums = new ArrayList<Integer>();
```
只能从 myNums 中读取元素,赋值给 Number 类型(还不能是其他类型):
```
Number n = myNums.get(0);
```
如果调用 add 会直接报编译错误:
```
myNums.add(45L); //compiler error
```
类似的,super 只能写不能读:

```
List<? super Number> myNums = new ArrayList<>();
myNums.add(1L); // legal
myNums.add(0.1); // legal
```
读会报错:
```
Number myNum = myNums.get(0); //compiler-error
```
谈一下我的理解。
Java 类型系统中 数组 和 集合 是会让人迷惑的。比如有两个类型,A 和 B,其中 A 是 B 的子类。那么 []A 也是 []B 的子类,可以这么写

```
[]A a = {...};
[]B b = a;
```

但是使用集合时,比如 List。List<A> 和 List<B> 没有半毛钱关系,这两个类型完全没有联系。
那么如何在集合中表达类型的上下限呢?就需要用到 ? 占位符、extends 和 super。
? 是类型占位符,表示这是一个类型,但是具体什么类型未知。比如 List<?> 表示一个未知类型的 List,但是这不是 raw List。
? 通常和 extends、super 一起使用。作为方法参数时,比如 List<T>,那么 List<? extends T> 可以接受任何 List<E>,其中 E 是 T 的子类,类型上限为 T ; List<? super T> 可以接受任何 List<E>,E 是 T 的超类,类型下线为 T。
一个例子是实现 泛型 Number 相加
```
static long sum(List<? extends Number> numbers) {
long summation = 0;
for (Number number : numbers) {
summation += number.longValue();
}
return summation;
}
```
那么 List<Integer>、List<Double> 等,传入 sum 中:
```
List<Integer> myInts = asList(1, 2, 3, 4, 5);
List<Long> myLongs = asList(1L, 2L, 3L, 4L, 5L);
List<Double> myDoubles = asList(1.0, 2.0, 3.0, 4.0, 5.0);
System.out.println(sum(myInts));
System.out.println(sum(myLongs));
System.out.println(sum(myDoubles));
```
如果单纯定义为:
```
static long sum(List<Number> numbers) {
long summation = 0;
for (Number number : numbers) {
summation += number.longValue();
}
return summation;
}
```
是没有什么意义的,这时传入 myInts 和 myLongs 会产生编译错误。


```
public static <T> void copy(List<? super T> dest, List<? extends T> src)
```
那么实例化时,比如说 T 是 Number。那么可以将 List<Integer> 拷贝到 List<Number> 甚至 List<Object> 中:
```
List<Integer> myInts = asList(1,2,3,4);
List<Double> myDoubles = asList(3.14, 6.28);
List<Object> myObjs = newArrayList<Object>();
copy(myInts, myObjs);
copy(myDoubles, myObjs);
```

最后谈一下 PECS 原则。如果我们只想从集合中读取元素,那么应该使用协变;如果我们只想向集合中加入元素,那么应该使用逆变,这也被称为 PECS 原则 (Produer Extends, Consumer Super)。
楼主如果感兴趣的话,还可以搜一下 Java 类型系统的协变、逆变看一下
339 天前
回复了 wqlin 创建的主题 深圳 从上海转战到深圳了
@BangBang #3 好嘞,谢谢哈
339 天前
回复了 wqlin 创建的主题 深圳 从上海转战到深圳了
@BangBang #1 谢谢哈,就是我走的时候最后一个月工资还没发,应该是等发了之后再去办理吗?
直接交给 HR 吗?缴费明细要自己打印吧
关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4399 人在线   最高记录 5043   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.3 · 10ms · UTC 02:25 · PVG 10:25 · LAX 19:25 · JFK 22:25
♥ Do have faith in what you're doing.