建议6:覆写变长方法也循规蹈矩 在Java中,子类覆写父类中的方法很常见,这样做既可以修正Bug也可以提供扩展的业务功能支持,同时还符合开闭原则(Open-Closed Principle),我们来看一下覆写必须满足的条件: 1.重写方法不能缩小访问权限. 2.参数列表必须与被重写方法相同. 3.返回类型必须与被重写方法的相同或是其子类. 4.重写方法不能抛出新的异常,或者超出父类范围的异常,但是可以抛出更少.更有限的异常,或者不抛出异常. public class Client { publi…
覆写equals方法必须覆写hashCode方法,这条规则基本上每个Javaer都知道,这也是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢?本建议就来解释该问题,我们先来看如下代码: public static void main(String[] args) { // Person类的实例作为Map的key Map<Person, Object> map = new HashMap<Person, Object>() { { put(new Per…
建议45: 覆写equals方法时不要识别不出自己 我们在写一个JavaBean时,经常会覆写equals方法,其目的是根据业务规则判断两个对象是否相等,比如我们写一个Person类,然后根据姓名判断两个实例对象是否相同,这在DAO(Data Access Objects)层是经常用到的.具体操作是先从数据库中获得两个DTO(Data Transfer Object,数据传输对象),然后判断它们是否是相等的,代码如下: class Person{ private String name; pub…
建议4: 避免带有变长参数的方法重载 在项目和系统的开发中,为了提高方法的灵活度和可复用性,我们经常要传递不确定数量的参数到方法中,在Java 5之前常用的设计技巧就是把形参定义成Collection类型或其子类类型,或者是数组类型,这种方法的缺点就是需要对空参数进行判断和筛选,比如实参为null值和长度为0的Collection或数组. 而 Java 5引入变长参数(varags)就是为了更好地提高方法的复用性,让方法的调用者可以“随心所欲”地传递实参数量,当然变长参数也是要遵循一定规则的,…
工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到. 下面以汽车制造为例,看看一般的工厂方法模式是如何实现的,代码如下: public class Client { public static void main(String[] args) { //生产车辆 Car car = CarFactory.createCar(FordCar.class); }…
对一个字符串拼接有三种方法:加号,contact方法,StringBuffer或者StringBuilder的append方法,其中加号是最常用的.其他两种方式偶尔会出现在一些开源项目中,那么这三者有什么区别? //加号拼接 str += "c"; //concat方法连接 str = str.concat("c"); 以上是两种不同的字符串拼接方式,循环5万次后再检查执行的时间,加号方式执行的时间是1438毫秒,而concat方法的执行时间是703毫秒,时间相差一…
建议5:别让null值和空值威胁到变长方法 public class Client { public void methodA(String str,Integer... is){ } public void methodA(String str,String... strs){ } public static void main(String[] args) { Client client = new Client(); client.methodA("China", 0); cli…
什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是用一个窄类型替换宽类型,而逆变则是用宽类型覆盖窄类型. 协变:宽类型------>窄类型 逆变:窄类型------>宽类型 class Base{ public Number doStuff(){ return 0; } } class Sub extends Base{ @Override pu…
建议41: 让多重继承成为现实 在Java中一个类可以多重实现,但不能多重继承,也就是说一个类能够同时实现多个接口,但不能同时继承多个类.但有时候我们确实需要继承多个类,比如希望拥有两个类的行为功能,就很难使用单继承来解决问题了(当然,使用多层继承是可以解决的).幸运的是Java中提供的内部类可以曲折地解决此问题,我们来看一个案例,定义一个父亲.母亲接口,描述父亲强壮.母亲温柔的理想情形,代码如下: //父亲 interface Father{ public int strong(); } //…
我们在实际开发中,经常需要覆写Object中的equals,hashcode,toString方法,其实编写这些代码并不是很难,但很枯燥和乏味. 下面推荐Google的Guava jar包来覆写上面的方法. 直接上代码. import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import com.google.common.collect.ComparisonChain; public…