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();
}
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.