目录
一、反射机制
1.一个需求引出反射
re.properties
classfullpath=com.feiyang.basic17_reflect.Cat
--method=hi
method=run
package com.feiyang.basic17_reflect;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class Cat {
private String name="招财猫";
public void hi(){
System.out.println("hi " + name);
}
public void run(){
System.out.println("run " + name);
}
}
package com.feiyang.basic17_reflect;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class ReflectionQuestion {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//需求:根据配置文件指定信息,创建Cat对象并调用方法
//传统实现方式:
/*Cat c = new Cat();
c.hi();*/
//明白反射
//1.读去配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String method = properties.get("method").toString();
System.out.println("classfullpath=" + classfullpath);
System.out.println("method=" + method);
//创建对象,传统方法行不通 =》 反射机制
Class aClass = Class.forName(classfullpath); //获取Class对象
Object o = aClass.newInstance(); //实例化对象
Method method1 = aClass.getMethod(method); //通过Class对象获取方法(方法对象)
method1.invoke(o); //调用方法
}
}
执行结果:
classfullpath=com.feiyang.basic17_reflect.Cat
method=run
run 招财猫
2.反射原理图
反射机制原理图:
3.反射相关类
package com.feiyang.basic17_reflect;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class Reflection01 {
public static void main(String[] args) throws Exception {
//1.读去配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String method = properties.get("method").toString();
Class c = Class.forName(classfullpath); //获取Class对象
Object o = c.newInstance(); //实例化对象
//获取构造器(无参)
Constructor constructor = c.getConstructor();
System.out.println(constructor);
//获取构造器(有参)
Constructor constructor1 = c.getConstructor(String.class, int.class);
System.out.println(constructor1);
//获取属性
Field age = c.getField("age");
System.out.println(age.get(o));
//获取方法
Method method1 = c.getMethod(method);
method1.invoke(o); //调用方法
}
}
执行结果:
public com.feiyang.basic17_reflect.Cat()
public com.feiyang.basic17_reflect.Cat(java.lang.String,int)
10
run 招财猫
4. 反射调用优化
代码示例:
re.properties
classfullpath=com.feiyang.basic17_reflect.Cat
method=hi
package com.feiyang.basic17_reflect;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class Cat {
private String name="招财猫";
public int age = 10;
public Cat(){
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public void hi(){
//System.out.println("hi " + name);
}
public void run(){
//System.out.println("run " + name);
}
}
package com.feiyang.basic17_reflect;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.Properties;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class Reflection02 {
public static void main(String[] args) throws Exception {
m1();
m2();
m3();
}
//传统方法调用
public static void m1(){
Cat cat = new Cat();
long l = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
cat.hi();
}
long l1 = System.currentTimeMillis();
System.out.println(l1-l);
}
//反射方式调用
public static void m2() throws Exception {
//1.读去配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String method = properties.get("method").toString();
Class c = Class.forName(classfullpath); //获取Class对象
Object o = c.newInstance(); //实例化对象
//获取方法
Method method1 = c.getMethod(method);
long l = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
method1.invoke(o); //调用方法
}
long l1 = System.currentTimeMillis();
System.out.println(l1-l);
}
//反射调用优化(禁止安全检查)
public static void m3() throws Exception {
//1.读去配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String method = properties.get("method").toString();
Class c = Class.forName(classfullpath); //获取Class对象
Object o = c.newInstance(); //实例化对象
//获取方法
Method method1 = c.getMethod(method);
method1.setAccessible(false);
long l = System.currentTimeMillis();
for (int i = 0; i < 900000000; i++) {
method1.invoke(o); //调用方法
}
long l1 = System.currentTimeMillis();
System.out.println(l1-l);
}
}
Relection02执行结果:
0
1954
1838
二、Class类
1.Class类分析
先看下Class类的类图:
可以看到Class类和别的类是一样的,同样继承了Object类,只是他的使用方法和所完成的功能有些特殊性,仅此而已(所以啦,不要觉得他很神秘呦)
示例:
package com.feiyang.basic17_reflect;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description: Class类分析
*/
public class Class01 {
public static void main(String[] args) throws ClassNotFoundException {
//传统方法
/**
* debug发现:
*
* ClassLoader类的方法,加载
* public Class<?> loadClass(String name) throws ClassNotFoundException {
* return loadClass(name, false);
* }
*/
Cat cat = new Cat();
//第2点:Class类对象不是new出来的,而是系统创建的
/**
* debug发现:
*
* 同样是ClassLoader类的方法,加载
* public Class<?> loadClass(String name) throws ClassNotFoundException {
* return loadClass(name, false);
* }
*/
Class c = Class.forName("com.feiyang.basic17_reflect.Cat");
//第3点:对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
//此处要把上面的new 注释掉,否则,debug不到ClassLoader
}
}
2.Class常用方法
package com.feiyang.basic17_reflect;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class Car {
public String brand = "奔驰";
public double price = 30.0;
public String color = "灰色";
}
package com.feiyang.basic17_reflect;
import java.lang.reflect.Field;
/**
* @author:飞扬
* @公众hao:程序员飞扬
* @description:
*/
public class Class02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//<?> 表示类型不确定
//1 获取Car类对应的Class对象
Class<?> cls = Class.forName("com.feiyang.basic17_reflect.Car");
//2 输出cls
System.out.println(cls);//显示cls对象,是哪个类的Class对象,class com.feiyang.basic17_reflect.Car
System.out.println(cls.getClass());//显示cls运行类型,class java.lang.Class
//3 得到包名
System.out.println(cls.getPackage().getName());//com.feiyang.basic17_reflect
//4 得到全类名
System.out.println(cls.getName());//com.fei