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,并以超链接形式标明文章原始出处,否则将 ...
随机推荐
- TCP/IP协议(一)
TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协 ...
- IOS开发UI基础UITextFidle相关属性
UITextFidle相关属性 • enablesReturnKeyAutomatically默认为No,如果设置为Yes,文本框中没有输入任何字符的话,右下角的返回按钮是disabled的. ...
- ADO.NET 基础
*程序要和数据库交互要通过ADO.NET进行,通过ADO.NET就能在程序中执行SQL了,ADO.NET中提供了对各种不同数据库的统一操作接口. 1.连接SQLServer 连接字符串,程序通过链接字 ...
- 数论 - 高精度Fibonacci数 --- UVa 10183 : How Many Fibs ?
How many Fibs? Description Recall the definition of the Fibonacci numbers: f1 := 1 f2 := 2 fn := f n ...
- PHP验证邮箱地址代码
PHP验证邮箱代码: function isEmail($email) { return strlen($email) > 6 && preg_match("/^[\w ...
- IIS配置ASP.NET和服务器错误页
以下两种方法均为全站出错处理 方法一: 1.在Web.config配置文件中<system.web></system.web>中添加<customErrors mode= ...
- VS2010 根据模型生成数据库 打开edmx.sql文件时 vs出现无响应的解决方案
今天在VS2010 sp1+sql server 2008 R2+Win7操作系统下测试ADO.NET 实体数据模型时 ,遇到这样一个问题. 首先建好实体模型,然后"根据模型生成数据库&qu ...
- 不可或缺 Windows Native (5) - C 语言: 数组
[源码下载] 不可或缺 Windows Native (5) - C 语言: 数组 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 数组 示例cArray.h #ifn ...
- 与众不同 windows phone (39) - 8.0 联系人和日历
[源码下载] 与众不同 windows phone (39) - 8.0 联系人和日历 作者:webabcd 介绍与众不同 windows phone 8.0 之 联系人和日历 自定义联系人存储的增删 ...
- 线段树或树状数组---Flowers
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=4325 Description As is known to all, the blooming tim ...