JavaSe——反射

1.获取class文件对象的三种方式

A.Object类的getClass()方法

B.数据类型的静态属性

C.Class类中的静态方法(开发中常用)

		public static Class<?> forName(String className) throws ClassNotFoundException
写的一个Person类:
package com.core.reflect;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void method() {
		System.out.println("method");
	}

	void function() {
		System.out.println("function");
	}

	private void show() {
		System.out.println("show");
	}
}

写的一个测试类:
package com.core.reflect;

public class ReflectDemo {

	/**
	 * @param args
	 * @throws ClassNotFoundException 
	 */
	public static void main(String[] args) throws ClassNotFoundException {
		// 方式1.Object类的getClass()方法
		Person p1 = new Person();
		Class c1 = p1.getClass();
		Person p2 = new Person();
		Class c2 = p2.getClass();
		System.out.println(p1 == p2);// false
		System.out.println(c1 == c2);// true
		System.out.println(c1);// class com.core.reflect.Person
		System.out.println(c2);// class com.core.reflect.Person
		System.out.println(p1);// com.core.reflect.Person@5ac2480b
		System.out.println(p2);// com.core.reflect.Person@5ac2480b

		// 方式2.数据类型的静态属性class
		Class c3 = Person.class;
		System.out.println(c3);//class com.core.reflect.Person
		
		//方式3.Class类的静态方法forname
		
		//Class c4 = Class.forName("Person");报错 java.lang.ClassNotFoundException
		Class c4 = Class.forName("com.core.reflect.Person");
		System.out.println(c4);//class com.core.reflect.Person
	}

}

2.通过反射获取构造方法(无参、带参、私有的构造方法)

A.通过反射获得无参的构造方法

Person类:
package com.core.reflect.demo1;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name, int age, String address) {

	}

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void method() {
		System.out.println("method");
	}

	void function() {
		System.out.println("function");
	}

	private void show() {
		System.out.println("show");
	}
}


测试类:
package com.core.reflect.demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectDemo {

	/**
	 * @param args
	 * @throws ClassNotFoundException
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// Constructor<?>[] getConstructors() :获取公共构造方法
		// getDeclaredConstructors() :获取所有的构造方法(包括私有的)
		Class c1 = Class.forName("com.core.reflect.demo1.Person");
		Constructor[] con1 = c1.getConstructors();
		Constructor[] con2 = c1.getDeclaredConstructors();
		for (Constructor constructor : con1) {
			System.out.println(constructor);
			//public com.core.reflect.demo1.Person()
		}
		System.out.println("---------");
		for (Constructor constructor : con2) {
			System.out.println(constructor);
//			com.core.reflect.demo1.Person(java.lang.String,int)
//			private com.core.reflect.demo1.Person(java.lang.String,int,java.lang.String)
//			public com.core.reflect.demo1.Person()
		}

		System.out.println("-----------");
		//获取单个构造方法
		Constructor con = c1.getConstructor();//返回构造方法对象
		Object obj = con.newInstance();//使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
		System.out.println(obj);//com.core.reflect.demo1.Person@2ce1b3b3
		Person p = new Person();
		System.out.println(p);//com.core.reflect.demo1.Person@15dcc3ca
	}

}


B.通过反射获得带参的构造方法

Person类:加了toString方法
package com.core.reflect.demo2;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name, int age, String address) {

	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void method() {
		System.out.println("method");
	}

	void function() {
		System.out.println("function");
	}

	private void show() {
		System.out.println("show");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}
	
}

测试类:
package com.core.reflect.demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectDemo {

	public static void main(String[] args) throws Exception {

		Class c1 = Class.forName("com.core.reflect.demo2.Person");
		Constructor con = c1.getConstructor(String.class, int.class);
		Object obj = con.newInstance("张三", 18);
		System.out.println(obj);//Person [name=张三, age=18, address=null]
		Person p = (Person) obj;
		System.out.println(p);//Person [name=张三, age=18, address=null]
	}

}



C.通过反射获得私有的构造方法

Person类
package com.core.reflect.demo3;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name, int age, String address) {
		this(name,age);
		this.address = address;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void method() {
		System.out.println("method");
	}

	void function() {
		System.out.println("function");
	}

	private void show() {
		System.out.println("show");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}

}
测试类:
package com.core.reflect.demo3;

import java.lang.reflect.Constructor;


public class ReflectDemo {

	public static void main(String[] args) throws Exception {
		//回顾:获得class对象的三种方式
		//A.对象的getClass静态属性
		Person p1 = new Person("张三", 18);
		Class c1 = p1.getClass();
		//B.数据类型的静态属性class
		Class c2 = Person.class;
		//C.Class.forName方法
		Class c3 = Class.forName("com.core.reflect.demo3.Person");
		System.out.println(c1);//class com.core.reflect.demo3.Person
		System.out.println(c2);//class com.core.reflect.demo3.Person
		System.out.println(c3);//class com.core.reflect.demo3.Person
		System.out.println(c1==c2);//true
		System.out.println(c2==c3);//true
		
		
		Constructor[] con1 = c3.getConstructors();
		for (Constructor constructor : con1) {
			System.out.println(constructor);
		}
//		public com.core.reflect.demo3.Person(java.lang.String,int)
//		public com.core.reflect.demo3.Person()
		System.out.println("-------");
		Constructor[] con2 = c3.getDeclaredConstructors();
		for (Constructor constructor : con2) {
			System.out.println(constructor);
		}
//		public com.core.reflect.demo3.Person(java.lang.String,int)
//		private com.core.reflect.demo3.Person(java.lang.String,int,java.lang.String)
//		public com.core.reflect.demo3.Person()
		//通过反射获得私有构造函数
		Constructor con = c3.getDeclaredConstructor(String.class,int.class,String.class);
		//暴力访问
		con.setAccessible(true);
		Object obj = con.newInstance("李四",22,"上海");
		//java.lang.IllegalAccessException
		System.out.println(obj);//Person [name=李四, age=22, address=上海]
	}

}

D.通过反射获得成员变量

Person类:
package com.core.reflect.demo4;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name, int age, String address) {
		this(name,age);
		this.address = address;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void method() {
		System.out.println("method");
	}

	void function() {
		System.out.println("function");
	}

	private void show() {
		System.out.println("show");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}

}

测试类:
package com.core.reflect.demo4;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;


public class ReflectDemo {

	public static void main(String[] args) throws Exception {
		Class c1 = Class.forName("com.core.reflect.demo4.Person");
		Constructor con1 = c1.getConstructor();//获得无参构造函数
		Field[] fields = c1.getFields();
		for (Field field : fields) {
			System.out.println(field);
//			public java.lang.String com.core.reflect.demo4.Person.address
		}
		Field[] fields2 = c1.getDeclaredFields();
		for (Field field : fields2) {
			System.out.println(field);
//			private java.lang.String com.core.reflect.demo4.Person.name
//			int com.core.reflect.demo4.Person.age
//			public java.lang.String com.core.reflect.demo4.Person.address
		}
		
		//通过无参构造函数创建对象
		Object obj = con1.newInstance();
		//获取单个成员变量,并对其赋值
		//获得addres成员变量
		Field addresField = c1.getField("address");
		addresField.set(obj, "北京");
		System.out.println(obj);//Person [name=null, age=0, address=北京]
		
		System.out.println("------");
		//获得私有的成员变量,并对其赋值
		//获得name成员变量
		Field nameField = c1.getDeclaredField("name");
		nameField.setAccessible(true);
		//暴力访问
		nameField.set(obj, "张三");//java.lang.IllegalAccessException
		System.out.println(obj);
		
	}
}


E.通过反射获得无参无返回值的成员方法

Person类:
package com.core.reflect.demo5;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name, int age, String address) {
		this(name,age);
		this.address = address;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void method() {
		System.out.println("method...");
	}

	void function() {
		System.out.println("function");
	}

	private void show() {
		System.out.println("show...");
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}

}

测试类:
package com.core.reflect.demo5;

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

public class ReflectDemo {

	public static void main(String[] args) throws Exception {
		Class c1 = Class.forName("com.core.reflect.demo5.Person");
		Method[] methods = c1.getMethods();
		Method[] methods2 = c1.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
//		public java.lang.String com.core.reflect.demo4.Person.toString()
//		public void com.core.reflect.demo4.Person.method()
//		public final void java.lang.Object.wait() throws java.lang.InterruptedException
//		public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
//		public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
//		public boolean java.lang.Object.equals(java.lang.Object)
//		public native int java.lang.Object.hashCode()
//		public final native java.lang.Class java.lang.Object.getClass()
//		public final native void java.lang.Object.notify()
//		public final native void java.lang.Object.notifyAll()
		System.out.println("-------");
		for (Method method : methods2) {
			System.out.println(method);
		}
//		public java.lang.String com.core.reflect.demo4.Person.toString()
//		public void com.core.reflect.demo4.Person.method()
//		void com.core.reflect.demo4.Person.function()
//		private void com.core.reflect.demo4.Person.show()
		
		Constructor con = c1.getConstructor();
		Object obj = con.newInstance();
		Method m1 = c1.getMethod("method");//method是共有方法
		m1.invoke(obj);//method...,调用obj的method方法
		
		Method m2 = c1.getDeclaredMethod("show");//show是私有方法
		m2.setAccessible(true);
		m2.invoke(obj);//show...,调用obj的show方法
	}
}


F.通过反射获得带参带返回值的成员方法

Person类:
package com.core.reflect.demo6;

public class Person {
	private String name;
	int age;
	public String address;

	public Person() {
	}

	private Person(String name, int age, String address) {
		this(name, age);
		this.address = address;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public int sum(int a,int b) {
		return a+b;
	}

	private String show(String str) {
		return "show:"+str+",name="+name+",address="+address;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", address=" + address
				+ "]";
	}

}

测试类:
package com.core.reflect.demo6;

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

public class ReflectDemo {

	public static void main(String[] args) throws Exception {
		Class c1 = Class.forName("com.core.reflect.demo6.Person");
		Constructor con = c1.getConstructor();
		Object obj = con.newInstance();
		Field addressField = c1.getField("address");
		Field nameField = c1.getDeclaredField("name");
		nameField.setAccessible(true);
		addressField.set(obj, "北京");
		nameField.set(obj, "张三");

		// 获得带参带返回值的成员函数
		// 获得sum方法(sum为公共方法)
		Method m1 = c1.getMethod("sum", int.class,int.class);
		Object res = m1.invoke(obj, 10,20);
		System.out.println(res);//30
		
		Method m2 = c1.getDeclaredMethod("show", String.class);
		m2.setAccessible(true);//暴力访问
		Object res2 = m2.invoke(obj, "Java");
		System.out.println(res2);//show:Java,name=张三,address=北京
	}
}

G.通过反射获得带参带返回值的成员方法

先写学生类、老师类、工人类。
package com.core.reflect.demo7;

public class Student {
	public void love(){
		System.out.println("爱学习");
	}
}

package com.core.reflect.demo7;

public class Teacher {
	public void love(){
		System.out.println("爱教书");
	}
}


package com.core.reflect.demo7;

public class Worker {
	public void love(){
		System.out.println("爱工作");
	}
}

还有对应的配置文件class.txt
className=com.core.reflect.demo7.Student
methodName=love

测试类:
package com.core.reflect.demo7;

import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectDemo {

	public static void main(String[] args) throws Exception {
//		Student s1 = new Student();
//		Teacher t1 = new Teacher();
//		Worker w1 = new Worker();
//		s1.love();//爱学习
//		t1.love();//爱教书
//		w1.love();//爱工作
		//通过配置文件运行类中的方法
		
//		利用反射加载运行配置文件中的方法
		Properties prop = new Properties();
		FileReader fr = new FileReader("class.txt");
		prop.load(fr);
		fr.close();
		String className = prop.getProperty("className");
		String methodName = prop.getProperty("methodName");
		System.out.println(className+"::"+methodName);
		//com.core.reflect.demo7.Student::show
		Class c1 = Class.forName(className);
		Object obj	 = c1.newInstance();
		Method m1 = c1.getMethod(methodName);
		m1.invoke(obj);//爱学习
	}
}

H.通过反射越过泛型检查

如:我给你ArrayList<Integer>的一个对象,我想在这个集合中添加一个字符串数据,如何实现呢?

package com.core.reflect.demo8;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class ReflectDemo {

	public static void main(String[] args) throws Exception {
		ArrayList<Integer> arrayList = new ArrayList<>();
		arrayList.add(10);
		arrayList.add(20);
		
		System.out.println(arrayList);//[10, 20]
//		arrayList.add("hello");
		//The method add(Integer) in the type ArrayList<Integer> is not applicable for the arguments (String)
		Class c1 = arrayList.getClass();
		Method m1 = c1.getDeclaredMethod("add", Object.class);
		m1.invoke(arrayList, "Java");
		System.out.println(arrayList);//[10, 20, Java]
	}
}

I.通过反射给某个对象设置属性为某一个值

写一个Tool类:
package com.core.reflect.demo9;

import java.lang.reflect.Field;

public class Tool {
	public void setProperty(Object obj, String propertyName, Object value)
			throws NoSuchFieldException, SecurityException,
			IllegalArgumentException, IllegalAccessException {
		Class c1 = obj.getClass();
		Field field = c1.getDeclaredField(propertyName);
		field.setAccessible(true);//暴力访问
		field.set(obj, value);
	}
}

测试类:
package com.core.reflect.demo9;

public class ToolDemo {

	public static void main(String[] args) throws Exception {
		Tool tool = new Tool();
		Person p1 = new Person();
		tool.setProperty(p1, "name", "张三");
		tool.setProperty(p1, "age", 22);
		
		Dog d1 = new Dog();
		tool.setProperty(d1, "name", "大黄");
		tool.setProperty(d1, "color", "yellow");
		System.out.println(p1.toString());
		//Person [name=张三, age=22]
		System.out.println(d1.toString());
		//Dog [name=大黄, color=yellow]
	}

}

class Person {
	private String name;
	private int age;

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

}

class Dog {
	private String name;
	private String color;

	@Override
	public String toString() {
		return "Dog [name=" + name + ", color=" + color + "]";
	}

}

J.通过用户的增删改查引出中介

UserDao.java
package com.core.reflect.demo10;

public interface UserDao {
	public abstract	void add();
	public abstract	void delete();
	public abstract void modify();
	public abstract void find();
}

UserDaoImpl.java
package com.core.reflect.demo10;

public class UserDaoImpl implements UserDao {

	@Override
	public void add() {
		System.out.println("添加");
	}

	@Override
	public void delete() {
		System.out.println("删除");
	}

	@Override
	public void modify() {
		System.out.println("修改");
	}

	@Override
	public void find() {
		System.out.println("查找");
	}

}

UserDaoImpl2.java
package com.core.reflect.demo10;

public class UserDaoImpl2 implements UserDao {

	@Override
	public void add() {
		System.out.println("权限校验");
		System.out.println("添加");
		System.out.println("日志记录");
	}

	@Override
	public void delete() {
		System.out.println("权限校验");
		System.out.println("删除");
		System.out.println("日志记录");
	}

	@Override
	public void modify() {
		System.out.println("权限校验");
		System.out.println("修改");
		System.out.println("日志记录");
	}

	@Override
	public void find() {
		System.out.println("权限校验");
		System.out.println("查找");
		System.out.println("日志记录");
	}

}

UserDaoDemo.java
package com.core.reflect.demo10;

public class UserDaoDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		UserDao ud = new UserDaoImpl();
		ud.add();// 添加
		ud.delete();// 删除
		ud.modify();// 修改
		ud.find();// 查找
		System.out.println("------");
		// 每个操作都需要进行验证权限

		ud = new UserDaoImpl2();
		ud.add();
		// 权限校验
		// 查找
		// 日志记录
		ud.delete();
		ud.modify();
		ud.find();
	}

}

K.动态代理的概述和实现


什么是动态代理?

•    代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。

•    动态代理:在程序运行过程中产生的这个对象

•    而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理


l  在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib


l  Proxy类中的方法创建动态代理类对象

•    public static Object newProxyInstance(ClassLoaderloader,Class<?>[] interfaces,InvocationHandler h)

•    最终会调用InvocationHandler的方法

•    InvocationHandler

l Object invoke(Objectproxy,Method method,Object[] args)


MyInvocationHandler类:

package com.core.reflect.demo11;

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

public class MyInvocationHandler implements InvocationHandler {

	private Object target;

	public MyInvocationHandler(Object obj) {
		target = obj;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("代理对象-资格检验");
		Object obj = method.invoke(target, args);
		System.out.println("代理对象-日志记录");
		return obj;
	}

}
测试类:

package com.core.reflect.demo11;

import java.lang.reflect.Proxy;

public class UserDaoDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		UserDao ud = new UserDaoImpl();
		ud.add();// 添加
		ud.delete();// 删除
		ud.modify();// 修改
		ud.find();// 查找
		System.out.println("------");
		// 每个操作都需要进行验证权限

//		ud = new UserDaoImpl2();
//		ud.add();
//		// 权限校验
//		// 查找
//		// 日志记录
//		ud.delete();
//		ud.modify();
//		ud.find();
		System.out.println("=========");
		MyInvocationHandler handler = new MyInvocationHandler(ud);
		UserDao proxy = (UserDao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), handler);
		proxy.add();
		proxy.delete();
		proxy.modify();
		proxy.find();
		
//		代理对象-资格检验
//		添加
//		代理对象-日志记录
//		代理对象-资格检验
//		删除
//		代理对象-日志记录
//		代理对象-资格检验
//		修改
//		代理对象-日志记录
//		代理对象-资格检验
//		查找
//		代理对象-日志记录
		System.out.println("-------");
		StudentDaoImpl studentDao = new StudentDaoImpl();
		MyInvocationHandler handler2 = new MyInvocationHandler(studentDao);
		StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(studentDao.getClass().getClassLoader(), studentDao.getClass().getInterfaces(), handler2);
		proxy2.regist();
		proxy2.login();
		
//		代理对象-资格检验
//		登陆
//		代理对象-日志记录
//		代理对象-资格检验
//		注册
//		代理对象-日志记录
	}

}

Over.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值