java反射

反射


----文章根据b站求知讲堂av76235341编写

问题1:为什么要有反射?

    1.在运行时判断任意一个对象所属的类
    2.在运行时构造任意一个类的对象
    3.在运行时判断任意一个类所具有的成员变量和方法
    4.在运行时调用任意一个对象的成员变量和方法
    5.生成动态代理

问题2:怎么使用?

反射相关的主要API:

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造方法
在这里插入图片描述

1.实例化Class类对象的3种方法:

	    //1.第一种(通过类名获取,最安全,最常用)
		Class clazz1=Student.class;
		//2.第二种(通过类的相对位置获取)
		try {
			Class clazz2=Class.forName("反射.Student");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//第三种(通过对象获取)
		Student s=new Student();
		Class clazz3=s.getClass();

2.一些常用方法

使用反射可以取得:

1.实现的全部接口

public Class<?>[] getInterfaces()

确定此对象所表示的类或接口实现的接口。

2.所继承的父类

public Class<? Super T> getSuperclass()

返回表示此 Class 所表示的实体(类、接口、基本类型)的父类的 Class。

3.全部的构造器

public Constructor[] getConstructors()

返回此 Class 对象所表示的类的所有public构造方法。

public Constructor[] getDeclaredConstructors()

返回此 Class 对象表示的类声明的所有构造方法
  Constructor类中:
  取得修饰符: public int getModifiers();
 取得方法名称: public String getName();
 取得参数的类型:public Class<?>[] getParameterTypes();

4.全部的方法

public Method[] getDeclaredMethods()

返回此Class对象所表示的类或接口的全部方法

public Method[] getMethods()

返回此Class对象所表示的类或接口的public的方法

5.全部的Field

public Field[] getFields()

返回此Class对象所表示的类或接口的public的Field。

public Field[] getDeclaredFields()

返回此Class对象所表示的类或接口的全部Field。

三、通过反射调用类中的指定方法、指定属性
1.调用指定方法

通过反射,调用类中的方法,通过Method类完成。步骤:
1.通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
2.之后使用Object invoke(Object obj, Object[] args)进行调用(参数1是需调用该方法的对象),并向方法中传递要设置的obj对象的参数信息。
Object invoke(Object obj, Object … args)
说明:
1.Object 对应原方法的返回值,若原方法无返回值,此时返回null
2.若原方法若为静态方法,此时形参Object obj可为null
3.若原方法形参列表为空,则Object[] args为null
4.若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法。

2.调用指定属性

在反射机制中,可以直接通过Field类操作类中的属性,通过Field类提供的set()和get()方法就可以完成设置和取得属性内容的操作。

public Field getField(String name)

返回此Class对象表示的类或接口的指定的public的Field。
public Field getDeclaredField(String name)返回此Class对象表示的类或接口的指定的Field。
在Field中:
public Object get(Object obj) 取得指定对象obj上此Field的属性内容
public void set(Object obj,Object value) 设置指定对象obj上此Field的属性内容
在类中属性都设置为private的前提下,在使用set()和get()方法时,首先要使用Field类中的setAccessible(true)方法将需要操作的属性设置为可以被外部访问。
public void setAccessible(true)访问私有属性时,让这个属性可见。

四、动态代理

动态代理作用:
动态代理就是为了不改变类源代码的基础上,为其增加功能
步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法,以完成代理的具体操作。

2.创建被代理的类以及接口

3.通过Proxy的静态方法
newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个Subject接口代理

4.通过 Subject代理调用RealSubject实现类的方法
例子:
1.被代理类的接口

package 反射;

public interface TestI {
	public void test1();
}

2.被代理类

package 反射;

public class Test implements TestI{
	public void test1(){
		System.out.println("test");
		}	
}

3.代理类,要求实现InvocationHandler的invoke方法

package 反射;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyDemo implements InvocationHandler{

	Object target;//被代理的对象,实际方法的执行者
	ProxyDemo(Object target)
	{
		this.target=target;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		before();
		Object result=method.invoke(target, args);
		after();
		return result;
	}
	//调用invoke方法后执行
	private void after() {
		System.out.println("调用invoke方法后执行");
	}
	//调用invoke方法前执行
	private void before() {
		System.out.println("调用invoke方法前执行");
	}

}

4.主方法

package 反射;

import java.lang.reflect.Proxy;

/*
 * 动态代理
 */
public class Main2 {

	public static void main(String[] args) {
	    //创建被代理的对象
		Test t=new Test();
		//创建代理对象
		ProxyDemo h=new ProxyDemo(t);
		//参数1 :代理对象的类加载器      参数2: 被代理对象的接口   参数3:代理对象  
		TestI p=(TestI) Proxy.newProxyInstance(h.getClass().getClassLoader(),t.getClass().getInterfaces(), h);
		p.test1();
	}
		
}

运行结果
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值