Effective Java 41 Use overloading judiciously
The choice of which overloading to invoke is made at compile time.
// Broken! - What does this program print?
public class CollectionClassifier {
public static String classify(Set<?> s) {
return "Set";
}
public static String classify(List<?> lst) {
return "List";
}
public static String classify(Collection<?> c) {
return "Unknown Collection";
}
public static void main(String[] args) {
Collection<?>[] collections = {
new HashSet<String>(),
new ArrayList<BigInteger>(),
new HashMap<String, String>().values()
};
for (Collection<?> c : collections)
System.out.println(classify(c));
// the result will prints three times "Unknown Collection"
}
}
Selection among overloaded methods is static, while selection among overridden methods is dynamic.
The compile-time type of an object has no effect on which method is executed when an overridden method is invoked; the "most specific" overriding method always gets executed.
class Wine {
String name() { return "wine"; }
}
class SparklingWine extends Wine {
@Override String name() { return "sparkling wine"; }
}
class Champagne extends SparklingWine {
@Override String name() { return "champagne"; }
}
public class Overriding {
public static void main(String[] args) {
Wine[] wines = {
new Wine(), new SparklingWine(), new Champagne()
};
for (Wine wine : wines)
System.out.println(wine.name());
// This will print "wine" "sparking wine" "Champagne"
}
}
Principle
- A safe, conservative policy is never to export two overloadings with the same number of parameters.
public class SetList {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
List<Integer> list = new ArrayList<Integer>();
for (int i = -3; i < 3; i++) {
set.add(i);
list.add(i);
}
for (int i = 0; i < 3; i++) {
set.remove(i);
list.remove(i);
}
System.out.println(set + " " + list);
// This will prints [-3, -2, -1] [-2, 0, 2]
}
}
The call to set.remove(i)selects the overloading remove(E), where E is the element type of the set (Integer), and autoboxes I from int to Integer.
The call to list.remove(i), on the other hand, selects the overloading remove(int i), which removes the element at the specified position from a list.
2. The standard way to ensure behavior of the types of the same super class or interface as the parameter of a method is to have the more specific overloading forward to the more general.
public boolean contentEquals(StringBuffer sb) {
return contentEquals((CharSequence) sb);
}
Summary
You should generally refrain from overloading methods with multiple signatures that have the same number of parameters. You can name the method with same prefix rather than overloading the write method. Such as, these variants of ObjectOutputStream have signatures like writeBoolean(boolean), writeInt(int), and writeLong(long).
In some cases, especially where constructors are involved, it may be impossible to follow this advice. In that case, you should at least avoid situations where the same set of parameters can be passed to different overloadings by the addition of casts. In this case you have the option of exporting static factories instead of constructors (Item 1).
If such a situation cannot be avoided, for example, because you are retrofitting an existing class to implement a new interface, you should ensure that all overloadings behave identically when passed the same parameters.
Effective Java 41 Use overloading judiciously的更多相关文章
- Effective Java 11 Override clone judiciously
Principles If you override the clone method in a nonfinal class, you should return an object obtaine ...
- Effective Java 42 Use varargs judiciously
Implementation theory The varargs facility works by first creating an array whose size is the number ...
- Effective Java 74 Implement Serializable judiciously
Disadvantage of Serializable A major cost of implementing Serializable is that it decreases the flex ...
- Effective Java Index
Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...
- 《Effective Java》读书笔记 - 7.方法
Chapter 7 Methods Item 38: Check parameters for validity 直接举例吧: /** * ...其他的被我省略了 * @throws Arithmet ...
- Effective Java 第三版——41.使用标记接口定义类型
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 目录
<Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...
- 【Effective Java】阅读
Java写了很多年,很惭愧,直到最近才读了这本经典之作<Effective Java>,按自己的理解总结下,有些可能还不够深刻 一.Creating and Destroying Obje ...
- [Effective Java]第八章 通用程序设计
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
随机推荐
- onhashchange事件,只需要修改hash值即可响应onhashchange事件中的函数(适用于上一题下一题和跳转页面等功能)
使用实例: 使用onhashchange事件做一个简单的上一页下一页功能,并且当刷新页面时停留在当前页 html: <!DOCTYPE html><html><body& ...
- Java魔法堂:注解用法详解——@SuppressWarnings
一.前言 编码时我们总会发现如下变量未被使用的警告提示: 上述代码编译通过且可以运行,但每行前面的“感叹号”就严重阻碍了我们判断该行是否设置的断点了.这时我们可以在方法前添加 @SuppressWar ...
- 如何将Mac OS X10.9下的Python2.7升级到最新的Python3.3
Mac OS X10.9默认带了Python2.7,不过现在Python3.3.3出来了,如果想使用最新版本,赶紧升级下吧.基本步骤如下. 第1步:下载Python3.3 下载地址如下: Python ...
- 一个关于explain出来为all的说明及优化
explain sql语句一个语句,得到如下结果,为什么已经创建了t_bill_invests.bid_id的索引,但却没有显示using index,而是显示all扫描方式呢,原来这还与select ...
- Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用
最近一直在做一些技术性的研究和框架改进工作,博客也落下好几天没有更新了,也该是时候静下心来,总结这段时间的一些技术改进的经验了.和上一阶段的CRM系统开发和技术研究一样,我都喜欢在一个项目或者模块完成 ...
- background的属性和背景图片定位的实例
本文内容: 1.背景图片定位示例 2.background常用的属性值 3.background-repeat新增的round.space属性 4.background-size的属性值(着重介绍co ...
- Oracle基本操作汇总
--10g 新增的表空间类型:大文件 (Bigfile) 表空间.--10g 数据库在创建的时候,会指定默认的表空间类型.如果不特殊指定的话,默认为 SMALLFILE 类型的表空间.SELECT * ...
- Tesseract-OCR引擎 入门
OCR(Optical Character Recognition):光学字符识别,是指对图片文件中的文字进行分析识别,获取的过程. Tesseract:开源的OCR识别引擎,初期Tesseract引 ...
- 不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符
[源码下载] 不可或缺 Windows Native (8) - C 语言: 结构体,共用体,枚举,类型定义符 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 结构体 ...
- 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP
[源码下载] 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP 作者:webabcd 介绍重新想象 Windows 8 Store ...