反射入门
properties文件
classfullpath=com.Zh.Cat
method=cry
Cat对象
package com.Zh;
/**
* @author OZH
* @Description:
* @date 2022/3/8 14:31
*/
public class Cat {
private String name = "黑猫";
public void hi() {
System.out.println("呵呵"+name);
}
public void cry() {
System.out.println("cry"+name);
}
}
ReflectionQuestion
package com.Zh.reflection.question;
import com.Zh.Cat;
import java.io.FileInputStream;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @author OZH
* @Description:反射的引入
* @date 2022/3/8 14:34
*/
public class ReflectionQuestion {
public static void main(String[] args) throws Exception{
//根据配置文件 re.properties 指定信息,创建Cat对象并调用方法hi
//传统的方式都是 new 对象 --> 调用方法
Cat cat = new Cat();
cat.hi();
//我们尝试做一做 ---> 明白 反射
//1.使用Properties 类,可以读写配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("reflexTest\\src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();//com.Zh.Cat
String methodName = properties.get("method").toString();
System.out.println("classfullpath = " + classfullpath);
System.out.println("method = " + methodName);
//使用反射机制解决
//1.使用反射机制解决
//(1)加载类,返回Class类型对象
Class<?> cls = Class.forName(classfullpath);//参数是类的全路径
//(2)通过cls 得到你加载的类 com.Zh.Cat 的对象实例
Object o = cls.newInstance();
System.out.println("o的运行类型 = " + o.getClass());
//(3) 通过cls得到你加载的类 com.Zh.Cat 的methodName "hi" 的方法对象
//即:在反射中,可以把方法视为(万物皆对象)
Method method = cls.getMethod(methodName);
//(4)通过method1 调用方法:即通过方法对象来实现方法
System.out.println("--------------------------------------");
method.invoke(o);// 传统方法 对象.方法(),反射机制 方法.invoke(对象)
}
}
反射机制
package com.Zh.reflection.question;
import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @author OZH
* @Description:
* @date 2022/3/8 16:46
*/
public class Reflection01 {
public static void main(String[] args) throws Exception{
//1.使用Properties 类,可以读写配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("reflexTest\\src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();//com.Zh.Cat
String methodName = properties.get("method").toString();
System.out.println("classfullpath = " + classfullpath);
System.out.println("method = " + methodName);
//使用反射机制解决
//1.使用反射机制解决
//(1)加载类,返回Class类型对象
Class<?> cls = Class.forName(classfullpath);//参数是类的全路径
//(2)通过cls 得到你加载的类 com.Zh.Cat 的对象实例
Object o = cls.newInstance();
System.out.println("o的运行类型 = " + o.getClass());
//(3) 通过cls得到你加载的类 com.Zh.Cat 的methodName "hi" 的方法对象
//即:在反射中,可以把方法视为(万物皆对象)
Method method = cls.getMethod(methodName);
//(4)通过method1 调用方法:即通过方法对象来实现方法
System.out.println("--------------------------------------");
method.invoke(o);// 传统方法 对象.方法(),反射机制 方法.invoke(对象)
//java.lang.reflect.Field : 代表类的成员变量,Field对象表示某个类的成员变量
//得到name字段
//getField不能得到私有的属性
Field nameField = cls.getField("age");//
nameField.get(o);//传统写法对象.成员变量,反射:成员变量对象.get(对象)
System.out.println("nameField.get(o) = " + nameField.get(o));
//java.lang.reflect.Constructor :代表类的构造方法,Constructor对象表示构造器
Constructor<?> constructor = cls.getConstructor();//()中可以指定构造器参数类型,返回的是无参构造器
System.out.println("无参构造器="+constructor);
Constructor<?> constructor1 = cls.getConstructor(String.class);
System.out.println("constructor1 = " + constructor1);//有形参的构造器
}
}
缺点:对执行速度有影响
反射调用优化
package com.Zh.reflection.question;
import com.Zh.Cat;
import java.lang.reflect.Method;
/**
* @author OZH
* @Description:测试反射调用的性能,和优化方案
* @date 2022/3/8 17:34
*/
public class Refection02 {
public static void main(String[] args) throws Exception{
m1();
m2();
m3();
}
//传统方法调用hi
public static void m1() {
Cat cat = new Cat();
long start = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
cat.hi();
}
long end = System.currentTimeMillis();
System.out.println("传统方法来调用hi 耗时="+(end-start));
}
//反射机制调用方法hi
//传统方法调用hi
public static void m2() throws Exception{
Class<?> aClass = Class.forName("com.Zh.Cat");
Object o = aClass.newInstance();
Method hi = aClass.getMethod("hi");
long start = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
hi.invoke(o);
}
long end = System.currentTimeMillis();
System.out.println("反射方法来调用hi 耗时="+(end-start));
}
//反射调用优化+关闭访问检查
public static void m3() throws Exception{
Class<?> aClass = Class.forName("com.Zh.Cat");
Object o = aClass.newInstance();
Method hi = aClass.getMethod("hi");
hi.setAccessible(true);//取消在反射调用方法时,取消访问检查
long start = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
hi.invoke(o);
}
long end = System.currentTimeMillis();
System.out.println("反射优化方法来调用hi 耗时="+(end-start));
}
}