JAVA小问题总结1
1对象构造过程:调用父类(若存在)构造函数------->Object构造函数-------->
初始化Object成员变量------------->父类成员变量------------->自身成员变量。
若过程中调用方法,子类重写了该方法,非静态方法的调用使用this指针,父类构造中也是调用子类同名方法,如果方法中含有成员变量,由于子类成员变量还没赋值,所以可能值为0或null。
public class Parent {
private int eatID=0;
public Parent(){
System.out.println("Parent is creating..");
eat();
}
public void eat(){
System.out.println("Parent is eat: "+eatID);
}
}
public class Son extends Parent {
private int eatID=1;
public Son(){
System.out.println("Son is creating..");
eat();
}
public void eat(){
System.out.println("Son is eat: "+eatID);
}
public static void main(String[] args){
Parent p=new Son();
}
}
结果为:
Parent is creating..
Son is eat: 0
Son is creating..
Son is eat: 1
2继承问题:子类构造时候,会先构造父类,所以子类中是包含父类所有的域和方法(包括保护和私有的),这样看可以看出子类继承父类所有的东西,但没有访问父类私有的东西。但从另一方面,父类私有的方法是不会被子类重写的,子类定义一个和父类同名的方法,使用反射调用invoke(Object,Object...)时,Object实际类型为父类,但使用子类对象时会被当成父类对处理,由于方法不能重写,所以该对象会调用父类的方法,而不是子类的。这样从方法继承来看,不能被重写,所以也可以看成子类不继承父类私有方法和域。
public class Test {
public static void main(String[] args) {
T2 t = new T2();
t.ff();
}
}
class T1 {
private int f() {
return 1;
}
}
class T2 extends T1 {
public void ff() {
try {
Class c = Class.forName("T1");
Method[] m = c.getDeclaredMethods();
m[0].setAccessible(true);
Object i = m[0].invoke(this, null); //这里调用私有方法时,参数不是父类对象也可以。
System.out.println(i);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
输出:1
修改T2类后结果一样
class T2 extends T1 {
private int f(){ //添加了一个和T1一样的私有方法,只是返回值不同,main中输出一样是
return 2; //T1的f()方法中的1,不是当前对象的2。
}
public void ff() {
try {
Class c = Class.forName("T1");
Method[] m = c.getDeclaredMethods();
m[0].setAccessible(true);
Object i = m[0].invoke(this, null);
System.out.println(i);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
输出:1