反射的引入![](https://i-blog.csdnimg.cn/blog_migrate/23e62aabe0ff706de38d9f56be091c91.png)
public class ReflectionQuestion {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//根据配置文件re.properties 指定信息 创建cat对象
//传统方法 new 对象 调用方法
/*Cat cat = new Cat();
cat.hi();*/
//使用Properties类,读写配置文件
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);
//2.想要创建对象? 行不通
//3.使用,反射机制解决
//(1)加载类 返回了一个Class的对象
Class aClass = Class.forName("reflaction.question.Cat");
//(2)通过cls得到你加载的类 reflection.question.Cat对象实例
Object o = aClass..getDeclaredConstructor().newInstance();
//通过aClass 得到你加载的类reflection.question.Cat的 method的方法对象
//即 在反射中,可以把方法视为对象。
Method method1 = aClass.getMethod(method);
//通过method1 调用方法(通过方法的对象来实现调用方法)
//传统方法是对象.方法(),反射机制是方法。invoice(对象)
System.out.println("====================");
method1.invoke(o);
}
}
反射相关的类
反射的优缺点
可以看的使用反射速度慢了不少
public static void m1(){
long star = System.currentTimeMillis();
for (int i = 0; i <1000000 ; i++) {
Cat cat = new Cat();
cat.hi();
}
long end = System.currentTimeMillis();
System.out.println(end - star);
}
//反射方式调用hi
public static void m2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> aClass = Class.forName("reflaction.question.Cat");
Object o = aClass.getDeclaredConstructor().newInstance();
Method hi = aClass.getMethod("hi");
long star = System.currentTimeMillis();
for (int i = 0; i <1000000 ; i++) {
hi.invoke(o);
}
long end = System.currentTimeMillis();
System.out.println( end - star);
}
反射优化
关闭反射检查。提供效率
Class类
常用方法![](https://i-blog.csdnimg.cn/blog_migrate/80c589e3b85116957adbea6b9fef5ac1.png)
public class Class_ {
private static Class<?> cls;
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
String classPath = "reflaction.question.Cat";
cls = Class.forName(classPath);
//1.获取到Car类 对应的Class对象
System.out.println(cls);
//输出真正的运行类型
System.out.println(cls.getClass());
//2.得到包名
System.out.println(cls.getPackage().getName());
System.out.println(cls.getPackageName());
//3.得到类名的名称
System.out.println(cls.getName());
//4.通过cls 创建对象实例
Cat cat = (Cat) cls.getDeclaredConstructor().newInstance();
System.out.println(cat);
//5.通过cls 反射得到对象属性 比如name
Field name = cls.getField("name");
System.out.println(name.get(cat));
//通过反射给对象属性赋值
name.set(cat,"咪咪");
System.out.println(name.get(cat));
//得到所有属性的字段
Field[] fields = cls.getFields();
for (Field o :fields) {
System.out.println(o.getName());
}
}
}
得到Class类 对象的6种方式
public static void main(String[] args) throws ClassNotFoundException {
//1.Class.forName
String path = "reflaction.question.Cat";
Class<?> cls1 = Class.forName(path);
System.out.println(cls1.getClass());
//2.类名。class 应用场景:参数传递
Class<Cat> cls2 = Cat.class;
System.out.println(cls2.getClass());
//3.对象.getClass() 应用场景,已有对象实例
Cat cat = new Cat();
Class cls3 = cat.getClass();
System.out.println(cls3.getClass());
//4.通过类加载器来获取Class对象 和3差不多
//(1)先得到类加载器 cat
ClassLoader classLoader = cat.getClass().getClassLoader();
//(2)通过类加载器得到Class对象
Class<?> cls4 = classLoader.loadClass(path);
System.out.println(cls4.getClass());
//5.基本数据类型 按如方式得到Class类
Class<Integer> integerClass = int.class;
Class<Double> doubleClass = double.class;
System.out.println(integerClass);
System.out.println(doubleClass);
//6基本数据类型对应的包装类可以通过.TYPE 得到Class对象
Class<Integer> type1 = Integer.TYPE;
Class<Character> type2 = Character.TYPE;
}
哪些类有Class对象。
public static void main(String[] args) {
Class<String> cls1 = String.class;//外部类
Class<Serializable> cls2 = Serializable.class;//接口
Class<Integer[]> cls3 = Integer[].class;//数组
Class<float[]> cls4 = float[].class;//二维|数组
Class<Thread.State> cls5 = Thread.State.class;//枚举
Class<Long> cls6 = long.class;//基本数据类型
Class<Void> cls7 = void.class;//Void数据类型
Class<Class> classClass = Class.class;//Class本身也是属于外部类
System.out.println(cls1);
System.out.println(cls2);
System.out.println(cls3);
System.out.println(cls4);
System.out.println(cls5);
System.out.println(cls6);
System.out.println(cls7);
}
动态和静态加载
类加载流程
在准备阶段,类的属性进行的操作
通过反射获取类的信息
修饰符有多个会叠加
通过反射创建对象
爆破用来访问私有的构造器,方法,属性。
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> aClass = Class.forName("reflaction.createConstructors.Cat");
//1.通过public的无参构造器创建实例
Object o = aClass.getDeclaredConstructor().newInstance();
Field name = aClass.getField("name");
name.set(o,"mimi");
System.out.println(o);
//2.通过public的有参构造器创建实例
//(1).先得到对应的构造器
Constructor<?> declaredConstructor = aClass.getConstructor(String.class );
//(2)创建实例 再传入实参
Object mimi = declaredConstructor.newInstance("咪咪");
System.out.println(mimi);
//3 通过非public的有参构造器创建实例
//(1)先得到private的构造器对象
Constructor<?> declaredConstructor1 = aClass.getDeclaredConstructor(String.class, int.class);
//爆破 使用反射可以使用私有的构造器
declaredConstructor1.setAccessible(true);
Object mimi1 = declaredConstructor1.newInstance("mimi", 1);
System.out.println(mimi1);
}
}
通过反射 访问类中的成员![](https://i-blog.csdnimg.cn/blog_migrate/1f39c3e95d572039d18ac77ad1ac241f.png)
public class Demo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> aClass = Class.forName("reflaction.createConstructors.Cat");
//操作公有的属性
Object o = aClass.getDeclaredConstructor().newInstance();
Field name = aClass.getField("name");
name.set(o,"小猫");
System.out.println(name.get(o));
//操作私有的属性
Field color = aClass.getDeclaredField("color");
color.setAccessible(true);
color.set(o,"红");
System.out.println(color.get(o));
}
}
通过反射调用方法
public class Demo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class<?> aClass = Class.forName("reflaction.createConstructors.Cat");
//操作公有的属性
Object o = aClass.getDeclaredConstructor().newInstance();
Field name = aClass.getField("name");
name.set(o,"小猫");
System.out.println(name.get(o));
//操作私有的属性
Field color = aClass.getDeclaredField("color");
color.setAccessible(true);
color.set(o,"红");
System.out.println(color.get(o));
//调用公有方法
Method method = aClass.getMethod("eat");
method.invoke(o);
//调用私有方法
Method declaredMethod = aClass.getDeclaredMethod("run");
declaredMethod.setAccessible(true);//爆破
declaredMethod.invoke(o);
}
}