展开全部
写个试试嘛
父子类定义
先写一个62616964757a686964616fe59b9ee7ad9431333361313935父类,定义方法和变量public class Father {
public String fatherPublicString = "father public";
protected String fatherProtectedString = "father protected";
private String fatherPrivateString = "father private";
public void fatherPublicMethod(){
System.out.println("father public method");
}
protected void fatherProtectedMethod(){
System.out.println("father protected method");
}
private void fatherPrivateMethod(){
System.out.println("father private method");
}
之后再写一个子类,定义方法和变量public class Child extends Father {
public String childPublicString = "child public";
protected String childProtectedString = "child protected";
private String childPrivateString = "child private";
public void childPublicMethod() {
System.out.println("child public method");
}
protected void childProtectedMethod() {
System.out.println("child protected method");
}
private void childPrivateMethod() {
System.out.println("child private method");
}
}
然后我们先看一下值子类能不能继承父类的一些共有私有属性
我们使用getDeclaredFields()和getFields()方法,想来看一下JDK帮助文档怎么定义者两个方法的* getFields() *
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
* getDeclaredFields() *
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
JDK帮助文档写的很清楚了,我就不再做解释了,主要看看getDeclaredFields()能不能获得父类的私有属性
代码//遍历Field数组
public static void iteratorField(Field[] fields) {
for (Field field : fields) {
System.out.println(field.getName());
}
System.out.println("-------------------------");
}
Class> childClass = Class.forName("com.reflection.Child");
Client.iteratorField(childClass.getFields());
Client.iteratorField(childClass.getDeclaredFields());
摸摸搭,我们来看一下结果//getFields
childPublicString
fatherPublicString
-------------------------
//getDeclaredFields
childPublicString
childProtectedString
childPrivateString
-------------------------
结果让我很失望,表示使用getFields将继承的public共有属性给弄过来了,虽然getDeclaredFields将private属性和protected属性也获得到了,但是他居然没有得到从父类继承下来的public共有属性!!虽然APi说的很清楚,但是这样的话怎么对父类的属性进行处理呢??还有protected属性应该也是能够获得的啊,没办法,换方法.try {
System.out.println(name +" field " +class1.getField(name));
System.out.println("-------------------------");
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
System.out.println(e.getMessage() + " NoSuchFieldException");
}
try {
System.out.println(name +" declaredField " + class1.getDeclaredField(name));
System.out.println("---------------------------------------------");
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
System.out.println(e.getMessage() + " NoSuchFieldException");
}
Client.getField(childClass, "fatherPublicString");
Client.getField(childClass, "fatherProtectedString");
Client.getField(childClass, "fatherPrivateString");
结果…..还是没有办法得到啊,怎么破?fatherPublicString field public java.lang.String com.reflection.Father.fatherPublicString
---------------------------------------------------------------------------------------
fatherPublicString NoSuchFieldException
fatherProtectedString NoSuchFieldException
fatherProtectedString NoSuchFieldException
fatherPrivateString NoSuchFieldException
fatherPrivateString NoSuchFieldException12345671234567
没办法只有用getSuperClass()获得父类了//其他方法不变
Client.getField(childClass.getSuperclass(), "fatherPublicString");
Client.getField(childClass.getSuperclass(), "fatherProtectedString");
Client.getField(childClass.getSuperclass(), "fatherPrivateString");
//结果getDeclaredField方法正常拿到父类的public,protected,private属性
fatherPublicString field public java.lang.String com.reflection.Father.fatherPublicString
-------------------------
fatherPublicString declaredField public java.lang.String com.reflection.Father.fatherPublicString
---------------------------------------------
fatherProtectedString NoSuchFieldException
fatherProtectedString declaredField protected java.lang.String com.reflection.Father.fatherProtectedString
---------------------------------------------
fatherPrivateString NoSuchFieldException
fatherPrivateString declaredField private java.lang.String com.reflection.Father.fatherPrivateString
---------------------------------------------
好吧,我也是心醉了,都继承了,我还拿不到父类的private,protected对象,非的我从父类拿,QAQ,这个先放一放,看看Method能给我们带来什么惊喜
Method的private,protected,private方法探讨
还是一样,我们通过getDeclaredMethods()和getMethods()来获得Method方法,一下是这两个方法的定义* getMethods() *
返回一个包含某些 Method 对象的数组,这些对象反映此 Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
* getDeclaredMethods() *
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
人家都告诉你了可以有从超类上继承的东东,看来有希望了,我们测试下://获得的Method方法迭代打出
public static void iteratorMethods(Method[] methods){
for(Method method : methods){
System.out.println(method.getName());
}
System.out.println("---------------------------------------------");
}
//客户端调用,我调!我调!
Class> childClass = Class.forName("com.reflection.Child");
Client.iteratorMethods(childClass.getMethods());
Client.iteratorMethods(childClass.getDeclaredMethods());12345678910111234567891011
结果ing…..
childPublicMethod
fatherPublicMethod
wait
wait
wait
hashCode
getClass
equals
toString
notify
notifyAll
---------------------------------------------
childPublicMethod
childProtectedMethod
childPrivateMethod
---------------------------------------------
俺内心是拔凉拔凉的…………..,也是只能得到子类的一些方法,继承的protected, private呢?!我们获得他的父类,打印一下看看fatherPublicMethod
wait
wait
wait
hashCode
getClass
equals
toString
notify
notifyAll
---------------------------------------------
fatherPublicMethod
fatherProtectedMethod
fatherPrivateMethod
--------------------------------------------
那我最后就可以得到一个结论:继承的话,private, protected都会被继承下来,private只有内部类,才会对其暴露.或者是被包装的protected,public包装的private可以被访问(话说有这么用么?这不是自己找罪受么?)
第二个问题,其实我这个问题有点错误,其实可以从反射中获得,只不过方法不是那么直接罢了,我们看下面的程序private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
//子类得不到,我们就从父类拿喽!
Class superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
获得method方法也是如此,子类的得不到就一直遍历,查找父类,获得想要的Field or Method.
总结
public , protected是会被子类继承的,private的继承有条件—内部类
父类的protected,private的Field和Method没有办法被直接得到,只有通过递归遍历superClass进行查找
以后我们写程序的时候如果需要修改protected或者是private值,尽量为其创建一个public的set方法,方便反射调用(这也很好的解释了spring的注入,一开始建议不要写在Field上)