1、分析如下代码
class Confusing
{
private Confusing(Object o)
{
System.out.println("Object");
}
private Confusing(double[] dArray)
{
System.out.println("double array");
}
public static void main(String[] args)
{
new Confusing(null);
}
}
- 运行结果是:double array
- Java的重载解析过程是以两阶段运行的:
- 第一阶段 选取所有可获得并且可应用的方法或构造器;
- 第二阶段在第一阶段选取的方法或构造器中选取最精确的一个。
- 如果一个方法或构造器可以接受传递给另一个方法或构 造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性
new Confusing((Object)null);
- 这样就可以确保只有Confusing(Object)是可应用的。更一般地讲,要想强制要求编译器选择一 个精确的重载版本,需要将实际的参数转型为形式参数所声明的类型。
- 以这种方式来在多个重载版本中进行选择是相当令人不快的。
- 在你的API 中,应该确保不会让客户端走这种极端。
- 理想状态下,你应该避免使用重载:为不同的方法取不同的名称。
- 如果你确实进行了重载,那么请确保所有的重载版本所接受的参数类型都互不兼容,这样,任何两个重载版本都不会同时是可应用的。
- 如果做不到这一点,那么就请确保所有可应用的重载版本都具有相同的行为
- 总之,重载版本的解析可能会产生混淆。
- 应该尽可能地避免重载,如果你必须进行重载,那么你必须遵守上述方针,以最小化这种混淆。
- 如果一个设计糟糕的API强制你在不同的重载版本之间进行选择,那么请将实际的参数转型为你希望调用的重载版本的形式参数所具有的类型。
2、代码分析
class Demo2
{
public static void main(String args[])
{
StringBuffer s=new StringBuffer();
s.append(1>5?100:'A');
s.append(6>5?90:'B');
System.out.println(s);
s.delete(0,s.length());
int i = 90;
s.append(1>5?i:'A');
s.append(6>5?i:'B');
System.out.println(s);
s.delete(0,s.length());
s.append(1>5?(int)100:'A');
s.append(6>5?(int)90:'B');
System.out.println(s);
System.out.println(6>5?100:'b');
System.out.println(1>5?'b':100.5);
}
}
//运行结果是:AZ 6590 AZ d 100.5
- jvm会根据参与运算的数据类推断类型,推断使用哪个方法
- 当将90赋值给int i时,'A'和'B'与i做运算会被提升为int型,就使用的是append(int)这个方法所以结果是6590
- 其他的情况,90 100都是作为常量存在,与字符做运算时,因为没有指定数据类型且可以被char这个数据类型所表示,所以被保存为char型。使用的是append(char)
- 即使使用强制类型转换也会被忽略,因为常量的数据类型转换会在编译器编译之前一步进行,所以不会起到强制类型转换的作用。