JAVA——Day 14反射机制

反射

反射机制,就是通过一个抽象的类名能够在自己记忆(加载类的内存)中找到相匹配的类的具体信息
注:java能够反射的前提:已经加载过这个类,就可以通过类名来寻找到这个类的所有相关信息

Java Reflection

Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能够直接操作任何对象的内部属性及方法
在这里插入图片描述在这里插入图片描述

一、Class类

在这里插入图片描述在这里插入图片描述在这里插入图片描述

package day14;

/**
 * 一、Class类
 */
public class ClassLearn {
	public static void main(String[] args) {
		Person p = new Person();
		Class clazz = p.getClass();	
		//clazz包含了p所属的Person类的所有信息
		
		Class c0 = Person.class;
		//创建指定类的class实例
		
		Class c1 = p.getClass();
		//通过一个类的实例对象的getClass()方法
		
		try {
			Class c2 = Class.forName("day14.Person");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//通过Class的静态方法forName(String name)
		//传入参数是包名.类名
		//常用
	}
}

通过反射调用类的完整结构

package day14;

public class Test {
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("day14.Student");
			Class superClass = clazz.getSuperclass();
			System.out.println("父类名:"+superClass.getName());
			//获取父类
			Class[] interfaces = clazz.getInterfaces();
			//获取当前类的所有接口
			for(Class a:interfaces) {
				System.out.println("接口:"+a.getName());
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

在这里插入图片描述

package day14;

import java.lang.reflect.Constructor;

public class Test {
	public static void main(String[] args) {
		try {
			Class clazz = Class.forName("day14.Student");
			Class superClass = clazz.getSuperclass();
			System.out.println("父类名:"+superClass.getName());
			//获取父类
			Class[] interfaces = clazz.getInterfaces();
			//获取当前类的所有接口
			for(Class a:interfaces) {
				System.out.println("接口:"+a.getName());
			}
			Constructor[] con = clazz.getConstructors();
			//获取类共有构造方法
			
			for(Constructor c :con) {
				System.out.println("构造方法名称:"+c.getName());
				System.out.println("修饰符是:"+c.getModifiers());
				//返回数字1代表public
			}
			
			Constructor[] con1 = clazz.getDeclaredConstructors();
			//获取类的所有构造方法
			
			for(Constructor c :con1) {
				System.out.println("构造方法名称:"+c.getName());
				System.out.println("修饰符是:"+c.getModifiers());
				Class[] cp = c.getParameterTypes();
				for(Class c2 :cp) {
					System.out.println("参数类型是:"+c2.getName());
				}
				//返回数字2代表private
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

通过反射创建一个对象&&调用私有构造

package day14;

import java.lang.reflect.Constructor;

/**
 * 通过反射创建一个对象
 */
public class ReflectCreatClassLearn {
	public static void main(String[] args) {
		try {
			testCraet();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void testCraet() throws Exception{
		Class clazz = Class.forName("day14.Student");
		Object obj = clazz.getDeclaredConstructor().newInstance();
		//Class.newinstance方法废弃了
		Student stu = (Student)obj;
		
		Constructor con = clazz.getConstructor(String.class);
		Student stu2 = (Student)con.newInstance("阳光小学");
		System.out.println(stu2.school);
		//Constructor.newInstance没被废弃
		//通过反射构造器的方法创建对象
		//通过反射机制可以强制的调用私有的构造方法
		Constructor pri = clazz.getDeclaredConstructor(String.class,int.class);
		pri.setAccessible(true);
		//解除私有封装,对私有方法强制调用
		Student stu3 = (Student)pri.newInstance("吼吼吼",123);
		System.out.println(stu3.age);
		System.out.println(stu3.name);
	}
}

反射机制获取类的方法

在这里插入图片描述

package day14;

import java.lang.reflect.Method;

/**
 * 通过反射机制来调用方法及私有方法
 *
 */
public class ReflectionGetPrivateMethod {
	public static void main(String[] args) {
		try {
			test();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private static void test() throws Exception{
		Class clazz = Class.forName("day14.Student");
		Method[] m = clazz.getMethods();
		//获取到类的所有公有方法
		for(Method s:m) {
			System.out.println(s.getName());	//方法名
			System.out.println(s.getReturnType());//返回值类型
			System.out.println(s.getModifiers());//修饰符
			Class[] obj = s.getParameterTypes();
			//参数类型,是一个数组,方法的参数几个,数组就几个元素
			if(obj != null && obj.length>0) {
				for(Class j:obj) {
					System.out.println("参数类型:"+j.getName());
				}
			}
			System.out.println("****************************");
		}
	}
}

反射机制获取类的属性和包

在这里插入图片描述

package day14;

import java.lang.reflect.Field;
/**
 * 反射机制调用类的属性
 */
public class ReflectionGetFieldAndPackageLearn {
	public static void main(String[] args) {
		try {
			testGetFieldAndPackage();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void testGetFieldAndPackage() throws Exception {
		Class clazz = Class.forName("day14.Student");
		Field[] fd = clazz.getDeclaredFields();
		//不包含父类属性
		Field[] fd2 = clazz.getFields();
		//公有属性,包含父类公有属性
		for(Field f:fd) {
			System.out.println("修饰符:"+f.getModifiers());
			System.out.println("值类型:"+f.getType());
			System.out.println("属性名:"+f.getName());
		}
		
		Package p = clazz.getPackage(); //获取包
		System.out.println(p.getName());
	}
}

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

在这里插入图片描述

调用指定方法

package day14;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * 使用反射机制调用指定方法和属性
 *
 */
public class ReflectUseMethodAndFieldLearn {
	public static void main(String[] args) {
		try {
			testuse();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 此时obj对象就相当于Student类的实例化
	 */
	public static void testuse() throws Exception{
		Class clazz = Class.forName("day14.Student");
		Constructor con = clazz.getConstructor();
		Object obj = con.newInstance();
		Method m = clazz.getMethod("movetype");
		m.invoke(obj);
		//不能调用private的方法
		
		Method m2 = clazz.getDeclaredMethod("testReflectGetPrivate");
		//可以访问到private方法
		m2.setAccessible(true);//强制调用
		m2.invoke(obj);
	}
}

调用指定属性

在这里插入图片描述

package day14;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
 * 使用反射机制调用指定属性
 *
 */
public class ReflectUseMethodAndFieldLearn {
	public static void main(String[] args) {
		try {
			testuse();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void testuse() throws Exception{
		Class clazz = Class.forName("day14.Student");
		Constructor con = clazz.getConstructor();
		Student stu = (Student)con.newInstance();
		Field f = clazz.getDeclaredField("secrect");
		f.setAccessible(true);
		f.set(stu, "秘密能说?");//对stu对象的secrect属性设置
		System.out.println(f.get(stu));
		//获取stu对象的secrect属性的值
		
	}
}

Java动态代理

在这里插入图片描述

package day14;

public interface Itest {
	void test1();
	void test2();
}

package day14;

/**
 * Java动态代理
 */
public class JavaDynamicProxyLearn implements Itest{
	@Override
	public void test1() {
		System.out.println("这是方法一");
	}

	@Override
	public void test2() {
		System.out.println("这是方法二");
	}
}

package day14;

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

/**
 * 这是动态代理类
 */
public class ProxyDemo implements InvocationHandler{
	
	Object obj;//被代理的对象
	public ProxyDemo(Object obj) {
		this.obj =obj;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println(method.getName()+"方法开始执行");
		Object result = method.invoke(this.obj,args);
		//执行的是指定代理对象的指定方法
		System.out.println(method.getName()+"方法执行完毕");
		return result;
	}
	
}

package day14;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class TestProxy {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JavaDynamicProxyLearn jd = new JavaDynamicProxyLearn();
		jd.test1();
		jd.test2();
		/**
		 * 需求
		 * 在执行test1,test2方法时需要加东西
		 * 在执行方法前打印test1或test2开始执行
		 * 在执行方法后打印test1或test2执行完毕
		 */
		InvocationHandler handler = new ProxyDemo(jd);
		/**
		 * Proxy.newProxyInstance(loader, interfaces, h)
		 * 参数1是代理对象的类加载器
		 * 参数2是被代理对象的接口
		 * 参数3是代理对象
		 * 返回的值就是成功被代理后的对象
		 */
		Itest t = (Itest)Proxy.newProxyInstance(
				jd.getClass().getClassLoader()
				, jd.getClass().getInterfaces(), handler);
		//注意这里要用接口来转换,参数1和参数2用的是要代理的对象,不是InvocationHandler的对象
		t.test1();
		t.test2();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值