- 一、反射介绍
- 1.1、什么是反射
- 1.2、反射的作用
- 二、创建对象过程
- 2.1、创建对象的三个阶段
- 2.2、创建对象时的内存结构
- 2.3、获取Class对象的三中方式
- 2.3.1、通过getClass()方法
- 2.3.2、通过.class静态属性
- 2.3.3、通过Class类 中的静态方法forName()
- 2.4、获取类的构造方法
- 2.4.1、方法说明及使用
- 2.4.1、通过构造方法创建对象
- 2.5、获取类的成员变量
- 2.5.1、方法说明及说明
- 2.5.2、操作成员变量
- 2.6、获取类的方法
- 2.6.1、方法介绍
- 2.6.1、调用方法
- 2.7、获取类的其他信息
- 三、反射具体实现
- 四、反射机制的效率
- 4.1、setAccessible()方法
- 五、总结
一、反射介绍 1.1、什么是反射 1.2、反射的作用
二、创建对象过程 2.1、创建对象的三个阶段 2.2、创建对象时的内存结构
package wr.oyc;
public class GetClass1 {
public static void main(String[] args) {
User user = new User();
Class class1 = user.getClass();
Class class2 = user.getClass();
System.out.println(class1);
System.out.println(class1.getName());
System.out.println(class1 == class2);
}
}
2.3.2、通过.class静态属性
package wr.oyc;
public class GetClass2 {
public static void main(String[] args) {
Class class1 = User.class;
Class class2 = User.class;
System.out.println(class1);
System.out.println(class1.getName());
System.out.println(class1 == class2);
}
}
2.3.3、通过Class类 中的静态方法forName()
package wr.oyc;
public class GetClass3 {
public static void main(String[] args) throws Exception{
Class class1 = Class.forName("wr.oyc.User");
Class class2 = Class.forName("wr.oyc.User");
System.out.println(class1.getName());
System.out.println(class1);
System.out.println(class1 == class2);
}
}
2.4、获取类的构造方法
2.4.1、方法说明及使用
package wr.oyc;
import java.lang.reflect.Constructor;
public class GetConstructor1 {
public static void main(String[] args) throws NoSuchMethodException {
Class class1 = User.class;
//不出现User的private的构造方法
Constructor[] constructor = class1.getConstructors();
for (Constructor c:constructor) {
System.out.println(c);
}
System.out.println("-------------------------------------------");
//只要在User类中声明的构造方法都会出现
Constructor [] constructors = class1.getDeclaredConstructors();
for (Constructor c: constructors) {
System.out.println(c);
}
}
}
2.4.1、通过构造方法创建对象
package wr.oyc;
import java.lang.reflect.Constructor;
public class GetConstructor2 {
public static void main(String[] args) throws Exception{
//获取User类
Class class1 = User.class;
//获取构造方法
Constructor constructor = class1.getConstructor(int.class , String.class);
//创建对象
Object o = constructor.newInstance(18 , "oldlu");
//强转为User对象
User user = (User)o;
System.out.println(user.getUserid() + "t" + user.getUsername() + "t" + user.getClass());
}
}
2.5、获取类的成员变量
2.5.1、方法说明及说明
package wr.oyc;
import java.lang.reflect.Field;
public class GetField {
public static void main(String[] args) throws NoSuchFieldException {
//获取类
Class class1 = User.class;
//获取所有的成员变量
Field[] fields = class1.getFields();
for (Field fields1: fields) {
System.out.println(fields1);
}
System.out.println("------------------------");
Field[] class1Fields = class1.getDeclaredFields();
for (Field field: class1Fields) {
System.out.println(field);
}
System.out.println("------------------------");
Field a = class1.getDeclaredField("userid");
//会报错 因为getField只能找到public的
Field b = class1.getField("userid");
System.out.println(a);
System.out.println(b);
}
}
2.5.2、操作成员变量
package wr.oyc;
import java.lang.reflect.Field;
public class GetField1 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
//获取类
Class c = User.class;
//获取成员变量
Field field = c.getField("userid");
//对象的实例化操作
Object o = c.newInstance();
//对成员变量赋值
field.set(o , 20);
//获取成员变量
Object obj = field.get(o);
System.out.println(obj);
}
}
2.6、获取类的方法
2.6.1、方法介绍
package wr.oyc;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetMethod {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, ClassNotFoundException {
// //获取反射类
// Class class1 = User.class;
//
// //获取方法
// Method method = class1.getMethod("setUserid", int.class);
//
// //对象的实例化
// Object o = class1.newInstance();
//
// //通过setUserid赋值
// method.invoke(o , 18);
//
// //通过getUserid获取
// Method method1 = class1.getMethod("getUserid");
//
//
// Object object = method1.invoke(o);
//
// System.out.println(object);
// //第一种 获取User类
// // 获取类的方法
// Class class1 = User.class;
//
// //实例化对象
// Object object = class1.newInstance();
//
// //set方法赋值
// Method method = class1.getMethod("setUserid", int.class);
// System.out.println(method.getName());
// method.invoke(object , 18);
//
// Method method1 = class1.getMethod("getUserid");
// Object value = method1.invoke(object);
//
// System.out.println(value);
// //通过getClass获取user
// User user = new User() ;
// Class class2 = user.getClass();
//
// Object o = class2.newInstance();
//
// Method method1 = class2.getMethod("setUsername", String.class);
//
// method1.invoke(o , "欧阳冲");
//
// Method method2 = class2.getMethod("getUsername");
//
// Object value = method2.invoke(o);
//
// System.out.println(value);
//通过forName获取
Class class3 = Class.forName("wr.oyc.User");
Object o = class3.newInstance();
Method method = class3.getMethod("setUserid", int.class);
System.out.println(method.getName());
method.invoke(o , 18);
Method method1 = class3.getMethod("getUserid");
Object value = method1.invoke(o);
System.out.println(value);
}
}
2.6.1、调用方法
package wr.oyc;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class GetMethod2 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
//获取反射类
Class c = User.class;
//获取方法setUsername
Method method = c.getMethod("setUsername", String.class);
//创建对象
Object o = c.newInstance();
//执行方法
method.invoke(o , "oldlu");
// 获取方法getUsername
Method method1 = c.getMethod("getUsername");
// 执行获取getUsername方法
Object value = method1.invoke(o);
//获取值
System.out.println(value);
}
}
2.7、获取类的其他信息
package wr.oyc;
public class GetInfo {
public static void main(String[] args) {
// 获取类名
Class class1 = User.class;
System.out.println(class1.getName());
// 获取包名
Package package1 = class1.getPackage();
System.out.println(package1.getName());
// 获取超类
Class superClass = class1.getSuperclass();
System.out.println(superClass.getName());
//获取该类实现的所有接口
Class[] interfaceClass = class1.getInterfaces();
for (Class c :interfaceClass) {
System.out.println(c.getName());
}
}
}
三、反射具体实现
package wr.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException {
Demo demo = new Demo();
Class class1 = Demo.class;
Object o = class1.newInstance();
Method[] methods = class1.getMethods();
//如果传值进来了
if(args != null && args.length>0){
//看传进来的值 和我的方法中 来做一个匹配
for(String str : args) {
for (int i = 0; i < methods.length; i++) {
if (str.equalsIgnoreCase(methods[i].getName())) {
methods[i].invoke(o);
break;
}
}
}
}else{
demo.Method1();
demo.Method2();
demo.Method3();
}
}
}
如果我们给定方法执行顺序怎么做呢?
四、反射机制的效率
package wr.test;
import wr.oyc.User;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo1 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class class1 = User.class;
//实例化对象
User user = (User)class1.newInstance();
Method method = class1.getMethod("setUserid", int.class);
// method.setAccessible(true);
// 对反射的效率提高了
long start = System.currentTimeMillis();
for (int i = 0; i <100000000 ; i++) {
method.invoke(user , 18);
}
long end = System.currentTimeMillis();
System.out.println("反射消耗的时间" + (end - start) + "ms");
User user1 = new User();
long start1 = System.currentTimeMillis();
for (int i = 0; i <100000000 ; i++) {
// user.setUserid(18);
}
long end1 = System.currentTimeMillis();
System.out.println("普通消耗的时间" + (end1 - start1) + "ms");
}
}
4.1、setAccessible()方法
package wr.test;
import wr.oyc.User;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo2 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
User user = new User();
Class class1 = user.getClass();
Field field = class1.getDeclaredField("username");
// 私有的方法是看不见,如果不用field.setAccessible(true) IllegalAccessException会报错
// field.setAccessible(true);
field.set(user , "欧阳冲");
Object o = field.get(user);
System.out.println(o);
Method method = class1.getDeclaredMethod("setUserid" ,int.class);
method.setAccessible(true);
method.invoke(user ,19);
}
}
五、总结



