effective java 第四天

26.优先考虑泛型

27.优先考虑泛型方法

尽量使用泛型来使程序规范。使得类型安全。

这样使用泛型也是有缺点的,用通配符可以让方法更加灵活多变。

编译器会做类型推导。

类型擦除:

https://www.cnblogs.com/drizzlewithwind/p/6101081.html

28.利用有限制的通配符来提升API的灵活性

PECS:https://blog.csdn.net/xx326664162/article/details/52175283

为什么会出现这种情况:

对list来说,并不知道里面装的是什么类型,如果里面已经装了SmallApple的对象,那么再装入Apple对象就不合适了,为了避免这种情况,list干脆什么也不准装进去。

 

对list2来说,知道里面装的肯定是Apple或者其父类,所以Apple及她的子列都可以向转型为该类,所以允许add这些对象。

29.优先考虑类型安全的异构容器

部用一个Map<Class<?>, Object>来保存所有的爱好,使用Class<?>作为键记录每个爱好的类型,而用Object作为值不再区分它们的类型。当取出时,根据请求的类型从Map中查找相应的值,由于值是Object类型的,需要使用type.cast强制转换为type指定的类型。只要客户端按照API的要求使用,这里的强制转换一定不会出错。

局限性

这种实现方法有两种局限性。

首先,恶意的客户端可以破坏Favorites实例的类型安全。如果客户端传入原生态的Class对象和不一致的值对象,则会在getFavorite的cast时抛出ClassCastException异常。不过好在我们可以对这一情况加以约束。只需要在put时使用一个动态的转换就可以了:

一旦客户端传入值类型不一致,就立即抛出异常。

第二种局限性是它不能用于泛型化类型,例如,你无法把List<String>作为Favorites的键,因为List<String>.class是个语法错误。这一局限性还没有很好的解决方法。

30.用enum代替int常量

Java的枚举类型是功能十分齐全的类,Java的枚举本质上是int值。

除了完善int美剧模式的不足之外,枚举类型还允许添加任何的方法和域,并实现任意的接口。

特定于常量的方法实现:

在枚举中,switch不是一个很好的选择。

另外一个使用枚举的例子:算工资。

31.用实例域代替序数

如图所示:

如果按图一的方式,那么想让某几项对应同一值就是不行的,而且想把这些常量进行重新排序,也是不方便的。

32.用EnumSet

位域bit field :位域有着int枚举常量的所有缺点,甚至更多。当位域以数字形式打印时,翻译位域比翻译简单的int枚举常量要困难得多。甚至,要遍历位域表示的所有元素也没有很容易的方法。

 

EnumSet:

  • EnumSet是一个专为枚举类设计的集合类,EnumSet中所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。EnumSet的集合元素也是有序的,EnumSet以枚举值在Enum类的定义顺序来决定集合元素的顺序。
  • EnumSet在内部以位向量的形式存储,这种存储形式非常紧凑、高效,因此EnumSet对象占用内存很小,而且运行效率很好。尤其是当进行批量操作(如调用containsAll retainAll方法)时,如果其参数也是EnumSet集合,则该批量操作的执行速度也非常快。
  • EnumSet集合不允许加入null元素。如果试图插入null元素,EnumSet将抛出 NullPointerException异常。如果仅仅只是试图测试是否出现null元素、或删除null元素都不会抛出异常,只是删除操作将返回false,因为没有任何null元素被删除。

33.用EnumMap代替序数索引

描述物理变化过程,常规方法:

利用EnumMap的方法:(可以把这个记住,作为状态转换的例子)

 

34.用接口模拟可伸缩的枚举

在用到Operation的时候,可以使用实现它的枚举

在尖括号里面可以这么写   接口之间用&连接。

 

猜你喜欢

转载自blog.csdn.net/weixin_38967434/article/details/82790851