java方法概述

检查参数的有效性
非公有的方法我们应该用断言的方法来检查它的参数,而不是使用通常大家所熟悉的检查语句来检测。如果我们使用的开发平台是JDK1.4 或者更高级的平台,我们可以使用assert结构;否则我们应该使用一种临时的断言机制。

有些参数在使用过程中是先保存起来,然后在使用的时候再进行调用,就必须做好检查工作,否则程序可能会抛出一些异常让你摸不着头 脑(如常见的空指针异常),也不能马上定位问题的所在位置,构造函数正是这种类型的一种体现,所以我们通常对构造函数参数的有效 性检查是非常仔细的。

总之,当编写一个方法或者构造函数的时候,应该考虑对应它的参数有哪些限制,并且要把这些限制写到文档中,在方法体的起始处,通 过显示的检查来实施这些限制。

需要时使用保护性拷贝
假设类的使用者会尽一切手段来破坏这个类的约束条件,在这样的前提下,你必须保护性地设计程序。面对客户的不良行为时仍然能保持 健壮性的类。
对于一个非可变类,可以考虑对其构造函数的可变参数采用保护性拷贝,如
public period(Date start, Date end){
this.start = new Date(start.getTime());
this.end = new Date(start.getTime());

// 接着做其他逻辑(保护性拷贝要在其他逻辑之前进行,并且有效性检查是针对拷贝后的对象,而不是原始对象)
}
对获取参数的get方法也要采用clone的方式返回,如:
public Date getStart(){
return (Date)start.clone();
}

非零长度的数组总是可变的,尽量使用非可变的对象作为内部组件,这样就不必关心保护性拷贝问题.

谨慎设计方法签名
1、谨慎选择方法的名字
① 选择易于理解的,并且与同一个包中的其他名字风格一致;
② 选择与大众认可的名字一致;
2、不要过于追求提供便利的方法。过多的方法会增加类的学习和使用成本,只有当一个操作被用得非常频繁的时候,才考虑为他提供一个 快加的方法。
3、避免过长的参数列表。太长的参数不便于使用者使用,尤其是参数类型相同的时候,很容易产生参数传递错误的问题。避免此类错误的 方法:
① 可以把一个方法分解成多个方法;
② 可以创建一个辅助类(helper class)。将参数组织成一个类作为参数传入;
4、对于类型参数,优先使用接口,而不是类。如参数为Map的时候,该方法可以接收Hashtable、HashMap、TreeMap等类型的参数。
5、谨慎使用函数对象

慎用重载
demo:
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));
}
}

预期结果是: "set","List" ,"Unknown Collection" 但是打印出来的却是三次"Unknown Collection"。在此程序中classify方法被重载了而调用哪个重载方法是在编译时决定的,循环中编译的类型都为Collection<?> ,所以每次调用这个方法。
对于 重载方法的选择是静态的,而对于被重写的方法的选择是动态的。

class Water {
String name() { return "Water " ; }
}
class Snow extends Water {
String name() { return “Snow” ; }
}
class Wine extends Water{
String name() { return "Wine " ; }
}
Public class Overriding {
public static void main(String[]args) {
Water[ ] waters= { new Water(),new Snow(),new Wine() };
for (Water water:waters)
System.out.println(water.name()));
}
}

打印出:"Water " “Snow” "Wine " 选择在编译时进行的,完全基于参数的编译时类型。
构造器重载中的特例:在java1.5发行之前,所有的基本类型都根本不同于所有的引用类型,但是在自动封装出现之后就出现了以下的情况:
   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);
}
}

实际发生情况是:set.remove(i)调用选择重载方法remove(E),这里的E是集合<Integer>类型,将从int自动装箱到Integer中,这是期望的行为而list.remove(i)调用选择重载方法remove(int i),他从列表指定位置上去除元素,从【-3,-2,-1,0,1,2】开始去除第零个元素,接着去除第一个,第二个,得到【-2,0,2】,要将list.remove的参数转化成Integer,迫使选择正确的重载方法,
for(int i=0;i<3;i++)  {
set.remove(i);
list.remove((Integer)i ); // or remove (Integer.valueOf(i))
}

List<E>接口有两个重载的remove方法:remove(E)和remove(int)在java1.5之前,List接口有一个remove(Object)而不是remove(E),相应的参数类型Object和int则根本不同,但自从有了泛型和自动装箱之后,破坏了List接口,所以自动装箱和泛型成了java语言的一部分之后,需要谨慎重载。

返回零长度的数组而不是null
如果返回null,对于每次调用到该方法的时候都需要做null判断,否则很容易抛出空指针异常,推荐返回一个零长度的数组,在通常情况 下,这样的做法对性能几乎没有影响。

为所有导出的API元素编写文档注释
需要增加注释的地方:类、接口、构造函数、方法和域声明,方法注释的内容:
调用该方法的前提条件;
调用后的后续处理(如捕获异常);
副作用(如方法启动线程后带来的安全性);
参数@param Describe;
返回@return Describe;
异常@throws if.....;
注意:注释中可以适用<p><code><tt>等HTML标签,但>,<等标签需要转义。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值