Java SE 064 使用反射机制调用对象的私有方法、访问对象的私有成员变量

(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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值