1.对于可变参数的问题:
①避免带有变长参数的方法的重载
public void calPrice(int price, int discount)
public void calPrice(int price ,int ...discount)
②避免null值和空值用于变长方法
public void methodA(String str,Integer... is)
public void methodA(String str,String... strs)
client.methodA("China")
client.methodA("China",null)
//同时存在问题:隐藏了实参类型,不确定null的实际类型
③复写的方法参数与父类相同,不仅仅是类型、数量,还包括显示形式。
class Base{ void fun(int price ,int... discounts){}}
class Sub extends Base{ @override void fun(int price, int[] disconts)}
Base base=new Sub(); base.fun(100,50);
Sub sub=new Sub(); sub.fun(100,50);//报错。
父类编译成字节码后的形参是一个int类型的形参加上一个int数组类型的形参,子类的参数列表也与此相同,故可以复写。
原因:事实上,base.fun(100,50),base对象是把子类对象Sub做了向上转型,形参列表是由父类决定的,由于是可变参数,在编译时,50被编译器编译成{50}数组,再由子类sub执行。sub.fun(100,50)中50不能被编译成{50}.
2.警惕自增的陷阱
int count=0;
for(int i=0;i<10;i++){count=count++;}
运行结果:count=0;
分析:count++是一个表达式,返回值为count自加前的值。处理过程:①JVM把count的值拷贝到临时变量区。②count的值加1。count=1③返回临时变量区的值,赋值给count。count=0.
count=count++的理解过程:
public int mockAdd(int count){int temp=count; count =count+1; return temp; }
3.少用静态导入
import java.text.NumberFormat;import static java.lang.Double.*;
import static java.lang.Math.*;
import static java.lang.Integer.*;
import static java.text.NumberFormat.*;
public class Test {
public static void main(String[] args){
String ar[]={"1","5"};
args=ar;
double s= PI* parseDouble(args[0]); //由于静态导入了Math包和Double包,故可以直接使用PI和parseDouble
NumberFormat nf=getInstance(); //但是不容易辨别getInstance()是那个类的方法
nf.setMaximumFractionDigits(parseInt(args[1]));//设置保留几位小数位
formatMessage(nf.format(s));
}
public static void formatMessage(String s){
System.out.println("面积是:"+s);
}
}
总结:适用于可以根据方法名辨别方法的用途的情况。
PS:自定义的方法名或常量不要与静态导入的相同。
4.