package com.vitas_01;public class Test { private Test(Object o) {
System.out.println("JavaFans");
} private Test(double c[]) {
System.out.println("I love Java");
} public static void main(String[] args) { new Test(null); }
} 这里的null 是作为什么传递的????
System.out.println("JavaFans");
} private Test(double c[]) {
System.out.println("I love Java");
} public static void main(String[] args) { new Test(null); }
} 这里的null 是作为什么传递的????
楼主【systeminok】截止到2008-06-29 20:58:43的历史汇总数据(不包括此帖):
发帖数:1 发帖分:40
结贴数:0 结贴分:0
未结数:1 未结分:40
结贴率:0.00 % 结分率:0.00 %
如何结贴请参考这里:http://topic.csdn.net/u/20080501/09/ef7ba1b3-6466-49f6-9d92-36fe6d471dd1.html
你见过 double[] param=null; 么!
我觉得是这样理解:Object是所有类的基类,它本身并没有显示的构造方法,但是lz的提问设计到是构造函数重载的问题,下面是我的个人见解,如果Object不去显示的构造它的对象,默认应该不会执行到它,除非new Test("参数")传的参数与double[]类型不匹配,才会执行到第一个构造函数,否则都会执行第二个
比如:
public class Test { private Test(Object o) {
System.out.println("JavaFans");
} private Test(double c[]) {
System.out.println("I love Java");
} public static void main(String[] args) {
Object o = null;
new Test(o); }
}
//上面执行第一个构造函数,因为显示创建了Object对象,并做参数调用构造方法public class Test { private Test(Object o) {
System.out.println("JavaFans");
} private Test(double c[]) {
System.out.println("I love Java");
} public static void main(String[] args) { new Test(2); }
}//"2"做参数,只会默认为int类型执行构造函数,所以也是执行第一个
如果多个构造函数的参数没有继承顺序就会报错,提示有多个匹配!例如:
public class Test {class A {
Double d[];}class B extends A {
Double d[];}
private Test(B b) {
System.out.println("BBBBBBBBBBBBBB");
} private Test(A a) {
System.out.println("AAAAAAAAAAAAAA");
} private Test(Object o) {
System.out.println("JavaFans");
} public static void main(String[] args) {new Test( null);}}它就会输出BBBBBBBB,因为调用顺序是自子类到父类! 再如:public class Test {private Test(int b[]) {
System.out.println("BBBBBBBBBBBBBB");
} private Test(int a[]) {
System.out.println("AAAAAAAAAAAAAA");
} private Test(Object o) {
System.out.println("JavaFans");
} public static void main(String[] args) {new Test( null);}}
就会报错,提示有多个匹配!
double c[]可以接受null
所以先执行该构造方法
下面的例子是一个原理public class Test {
Test(int i){
System.out.println("int");
}
Test(long i){
System.out.println("long");
}
public static void main(String[] args) {
new Test('a');
}
}
虽然你说的很长,但是不太赞同你说的观点你同样可以将这两个构造函数修改成:
public Test(Object o){
System.out.println("Object o Test!");
}
public Test(Object[] arr){
System.out.println("Object[] arr Test!");
}
同样可以通过编译,执行的结果依然是:Object[] arr Test!但是使用:
public Test(String o){
System.out.println("String s Test!");
}
public Test(String[] param){
System.out.println("String[] param Test!");
}
以上是不能通过编译的,
错误提示是:ambiguous引起歧义的。这应该体现了Object类的特别。
你是希望知道它是啥类型? 呵呵,14楼的帖子说了,
现在是拿调用时的实参去逐一匹配形参的类型,虚拟机在编译的时候根据参数的继承关系构造了一棵语法树,
匹配时由子类向父类的顺序。
为何不是父类向子类,呵呵,那就会每次匹配到object去了,它是java类的老祖宗阿!
只要实参能够转换为某一类型,就ok!
匹配冲突是为何呢?
A 父
/ \
B C 子如果一个对象既可以转换为B类型的,又可以转换为C类型的,你说编译器匹配给谁好啊?
这不是为难编译器么!
对于你的疑问,我的理解是,java把数组也当成了对象,不然不能将其设为null,也就是说任何数组是Object的子类,而不是它数据类型的子类,支持20楼
当然14楼的也没错
double [] 创建的是引用 可以是空,如果doubl[] int[] 创建2饮用的构造 个编译就会出错。无法区分null应该使用那个构造。如果没有int[] double[] 构造,使用null就调用Object的构造我的理解应该没错public class Test {
private Test(int[] a){
System.out.println("I love a");
}
private Test(double c[]){
System.out.println("I love Java");
}
private Test(int a){
System.out.println("I love a");
} private Test(Object o){
System.out.println("JavaFans");
} public static void main(String[] args) { new Test(null); }
}
就近原则啊.lz的问题中Object是 double[] 的父类, 所以匹配double[].后面有人举例 String, Sring[] 结果不能编译的情况,
那是因为这两个类没有父子关系, 所以不能编译.
System.out.println("JavaFans");
} private Test(double[] c) { //Java 中提倡把 [] 放数组元素类型 double 后面
System.out.println("I love Java");
} public static void main(String[] args) {
new Test(null);
new Test((double[]) null); //看看这句打印什么
new Test((Object) null); //这句呢
//明白了?
}}
基本正确,Java 中所有数组对象都是数组类的实例,所有类都直接或间接继承自 Object 类(除 Object 类本身)。
方法名相同,参数表不同,返回值类型可以不同。调用时要给出明确参数并确定调用某一方法。在编译时,编译器会根据参数选择适当的方法,所以重载也叫编译时多态。就近向上匹配原则
如果方法的参数表中的数据类型和调用时给出的参数类型不尽相同时会根据向上匹配的就近原则。(类型就近向上转化匹配)java中的参数传递,简单类型的变量传递的是数值,对象变量的传递则传递的一个引用(地址)。private Test(Object o) {//o是对象变量,对象变量的传递则传递的一个引用
System.out.println("JavaFans");
}private Test(double[] c) {//c是一种特殊对象变量,对象变量的传递则传递的一个引用
System.out.println("I love Java");
} new Test(null); //因为上面的方法接受的是引用,所以null对两个方法都可以传递进去;再根据“就近向上匹配原则”,优先传递给private Test(double[] c)
首先虚拟机将会找到适合调用的所有重载方法,然后判断最适合的重载方法的原则是——
如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么说明第一个方法比第二个方法缺乏精确性,虚拟机会选择更精确的方法所以这里的问题是数据对象和Object对象谁可以接受谁,楼主可以自己实验证明double[]更精确
首先。声明类型为Private、static、final和 构造函数(构造函数隐示声明为static) 属于方法的 “静态绑定”。在编译的时候匹配方法表中的方法签名就可以了。与之对应的是“动态绑定”。再次,关于重载解析,方法表中存放的是方法的方法签名,方法签名是由方法的名字和参数的类型组成。当出现多个相同方法名不同参数类型的时候发生重载解析。那楼主的问题就在于当在“静态绑定”的时候发生重载解析的过程。......
private Test(Object o) {
System.out.println("JavaFans");
} private Test(double c[]) {
System.out.println("I love Java");
}
......在细一点,问题就在于方法签名中相同方法名不同参数类型的问题了。也就是参数类型的问题了。如果方法的参数表中的数据类型和调用时给出的参数类型不尽相同时会根据向上匹配的就近原则。有兴趣试下用一个父类对象 和一个子类对象作为构造方法的参数,然后在实例化的时候传递个null 看看。
/*Super.java*/public class Super { public Super() {
super();
}}/*Sun.java*/public class Sun extends Super { public Sun() {
super();
} public Sun(Super f) {
System.out.println(" para : Super");
}
public Sun(Sun s) {
System.out.println("para : Sun");
}
}
/*Test.java*/
public class Test {
public static void main(String[] args) {
new Sun(null);
}}结果为:para : Sun
首先要搞明白值传递的问题。再次null是怎么回事?数组又是怎么回事?值传递的问题,随便纠正下52楼的家伙,java中只有值传递,没有引用传递。此值非彼值。一种值是基本数据类型。另一种值是对象的引用。二者都是以值的形式传递。null是怎么回事?如果将null指向一个对象变量,那么表示该对象变量不引用任何对象。也就是说不引用任何地址。数组又是怎么回事?这样来说吧。回到数组的创建上 int[] arr = new int[10]; new是否有似曾相识的感觉。我们在实例化一个对象的时候也要用到new。new其实是一种运算符,作用是动态分配存储地址。那arr就是一个地址的引用了。和一个对象变量大同小异了。
所以null对两个方法都可以传递进去;
System.out.println("JavaFans");
}
不了解,没碰到过此类的问题。
不过如果是double[] 的话,那应该是虚拟机在栈中找最近的,然后直接返回
但是个人人为两个都应该能传递进去,一个Object 指向null 和一个arr指向null并没有区别。
Compiled from "Test.java"
public class Test extends java.lang.Object{
public static void main(java.lang.String[]);
Code:
0: new #6; //class Test
3: dup
4: aconst_null
5: invokespecial #7; //Method "<init>":([D)V
8: pop
9: return}这是 javap 反编译出来的东西。我想知道为什么。#7为 invoke [D (double[]),
找牛人~~
2.就近原则.
3.首次匹配不考虑装箱.
//模棱两可的方法重载
//invoke有两个重载的方法,一个是Object作为参数,另一个是int[]作为参数,看看下面的程序会输出什么?
public static void main(String[] args) {
invoke(null);
invoke(2);
}
private static void invoke(Object obj) {
System.out.println("Object "+obj);
}
private static void invoke(int[] nums) {
System.out.println("Arrays "+nums);
}
}
Object 2
直接的说,如果调用的是父类的方法的话,那么建它的子类就没有什么必要了吧,
呵呵,楼主不知道我说的明不明白,这只是我个人的想法,
System.out.println("I love az");
}
private Test(String a) {
System.out.println("I love as");
}
private Test(Object o) {
System.out.println("JavaFans");
} public static void main(String[] args) { new Test(null); }
} 父类object
test(null)对子类String 和 int[]同时引用编译出错
从子到父挨个匹配,匹配上就调用