(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~
Java SE 064 使用反射机制调用对象的私有方法、访问对象的私有成员变量
文章目录
1.使用反射机制调用类的私有方法
1.1定义具有私有方法的类
package com.javareview.refelect.accessprivate;
/**
* 通过反射访问类的私有方法
* @author xiongjie
*
*/
public class AccessPrivate {
private String sayHello(String name){
return "hello " + name;
}
}
1.2通过反射调用类的私有方法
package com.javareview.refelect.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.javareview.refelect.accessprivate.AccessPrivate;
public class AccessPrivateTest {
public static void main(String[] args) {
AccessPrivate p = new AccessPrivate();
//s1.反射获取私有类对象的Class对象
Class<?> classType = p.getClass();
try {
//s2.反射获取私有方法对象
Method method = classType.getDeclaredMethod("sayHello", new Class[]{String.class});
//s3.压制java的访问控制检查
method.setAccessible(true);
//s3.通过反射调用执行私有方法
String str = (String) method.invoke(p, new Object[]{"xiongjie"});
System.out.println(str);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
2.访问控制检查
2.1压制java的访问控制检查
method.setAccessible(true);
(1)在SSH框架中,很多时候框架需要用到。
(2)Hibernate要求提供一个不代参数的构造方法,对类的属性提供set方法,get方法。只有提供了这样一种约定,Hibernate才能知道这个属性要想给它设置值的时候,应该调用什么方法,有的时候,没有提供这个方法,也能赋值,给private 的成员变量赋值,就是通过反射的方式来做到的。调用set方法也是通过反射来去调用的。
3.通过反射访问私有(private)属性
3.1定义具有私有属性的类
package com.javareview.refelect.accessprivate;
/**
* 通过反射访问类的私有属性
*/
public class PrivateAttribute {
/**
* 私有属性
*/
private String name = "zhangsan";
public String getName() {
return name;
}
}
3.2通过反射访问类的私有属性并修改私有属性的初始值
package com.javareview.refelect.accessprivate.test;
import java.lang.reflect.Field;
import com.javareview.refelect.accessprivate.PrivateAttribute;
/**
* 通过反射访问类的私有属性
*/
public class AccessPrivateAttributeTest {
public static void main(String[] args) {
PrivateAttribute pa = new PrivateAttribute();
//s1.通过反射获取私有属性类的Class对象
Class<?> classType = PrivateAttribute.class;
//s2.通过反射获取名为name的成员属性
try {
Field field = classType.getDeclaredField("name");
//s3.压制java对访问修饰符的检查
field.setAccessible(true);
//s4.修改属性的初始值
field.set(pa, "xiongjie");
System.out.println(pa.getName());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
4.关于反射的执行流程回顾
4.1获得Class对象
4.2生成对象
通用的方法是获得Constructor对象,然后调用它的newInstance()方法生成目标类的实例。或者说调用不带参数的构造方法,直接用Class对象的newInstance()方法,也可以通过调用不带参数的构造方法来生成目标类的实例。
4.3通过反射获取对象的属性与方法
(1)生成好对象之后,可以调用它的方法,获取它的属性,获取方法就是getDeclaredMethods(String name,动态参数——是Class对象类型的数组)方法,传入一个方法名字,一个Class对象类型的数组,即可变参数,获得一个Method对象.
(2)获取属性也是一样,getDeclaredField(String name),传入一个具体的名字,获得一个Field对象.
4.4通过反射调用对象的属性与方法
Method对象与Field对象都获得完之后,就可以去调用它们了。
(1)对于Method来说,就可以用Method的invoke(被调用方法所处的对象,参数所构成的Object类型的数组,即可变参数)方法
(2)如果是Field,就可以使用set或get方法访问到目标属性,可以去设置目标属性值,获取目标属性值。返回来的结果就是最终方法调用所返回来的结果,对于属性来说是不需要返回值的,因为设置属性是不需要返回值的。get属性是需要获得一个结果的。最后可以操纵这个结果。反射有固定的规律可循。
5.“Class” class
(1)众所周知Java有个Object class,是所有Java classses的继承根源,其内声明了数个应该在所有Java class中被改写的methods: hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class object.
(2)Class class十分特殊。它和一般classes一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(原生java类型,boolean,byte,char,short,int,long,float,double)以及关键词void。
当一个class被加载,或当加载器class loader的defineClass()被jvm调用,JVM会自动产生一个Class object。如果你想借由“修改java标准库源码”来观察Class object的实际生成时机(例如在Class的constructor内添加一个println()),不能够!因为Class并没有public constructor.
6.”Class” object的取得途径
java允许我们从多种途径为一个class生成对应的Class object。
6.1运用getClass()注:每个class都有此函数
运用getClass()
注:每个class都有此函数 String str =”abc”;
Class c1 = str.getClass();
6.2运用Class.getSuperclass()
Button b = new Button();
Class c1 = b.getClass();
Classs c2 = c1.getSuperclass();
6.3Class.forName()
运用static method Class.forName();(最常被使用)
Class c1 = Class.forName(“java.lang.String”)
Class c2 = Class.forName(“java.awt.Button”);
Class c3 = Class.forName(“java.util.LinkedList$Entry”);
Class c4 = Class.forName(“I”);
Class c5 = Class.forName(“[I”);
6.4运用.class语法
Class c1 = String.class
Class c2 = java.awt.Button.class
Class c3 = Main.InnerClass.class
Class c4 = int.class
Class c5 = int[].class
6.5运用primitive wrapper classes的TYPE语法
Class c1 = Boolean.Type
Class c2 = Byte.TYPE
Class c3 = Character.TYPE
Class c4 = Short.TYPE
Class c5 = Integer.TYPE
Class c6 = Long.TYPE
Class c7 = Float.TYPE;
Class c8 = Double.TYPE
Class c9 = Void.TYPE
lass c2 = Byte.TYPE
Class c3 = Character.TYPE
Class c4 = Short.TYPE
Class c5 = Integer.TYPE
Class c6 = Long.TYPE
Class c7 = Float.TYPE;
Class c8 = Double.TYPE
Class c9 = Void.TYPE