反射的作用有两点
第一点是获取任意一个类的信息
第二点是结合配置文件动态创建对象
什么是正射? 普通new就是正射 就像Student stu=new Student();
什么是反射? 不用普通new对象的形式,而是加载类的形式来获取该类里面的所有东西 包括成员变量 构造方法 成员方法 包括私有的全部都能获取出来
反射的特点:它可以拿到类里所有的东西 比如说私有的都能拿到
反射有三种创建形式
第一种:Class.forName();
特点:比较主动 它要求jvm去加载静态代码块
第二种:类名.class
特点: 非常不主动的加载方式 没有c1.newInstance()对象之前,它是不会要求jvm加载什么
等它用到了newInstance()实例方法之后,它才加载全部
第三种:对象.getClass()
特点: 构造器初始化整个类里面的所有东西 它要求jvm去加载所有,包括静态代码块,动态代码块和构造方法
总结: 不管用哪种方式,得到的肯定都是Class的类对象
它的三种方法都占用空间,只是先后循序不一样
代码展示
package com.bdqn.reflectdemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestStudent {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
//反射的作用
//1.获取任意一个类中的所有信息
//2.结合配置文件动态创建对象
//什么是正射?
//普通new就是整数 就像Student stu=new Student();
//什么是反射?
//不用普通new对象的形式,而是加载类的形式来获取该类里面的所有东西 包括成员变量 构造方法 成员方法 包括私有的全部都能获取出来
//反射的特点:它可以拿到类里所有的东西 比如说私有的都能拿到
//第一种比较主动 它要求jvm去加载静态代码块
Class c=Class.forName("com.bdqn.reflectdemo.Student");
System.out.println("-----------------------------");
//第二种 非常不主动的加载方式 它不要求jvm加载什么 等用到了newInstance() 它才加载全部
Class c1= Student.class;
System.out.println("-----------------------------");
//第三种 构造器初始化整个类里面的所有东西 它要求jvm去加载所有 包括静态代码块,动态代码块和构造方法
Class c2=new Student().getClass();
//总结 不管用哪种方式,得到的肯定都是Class的类对象c1
// 它三种方法都占用空间,只是先后循序不一样
System.out.println("---------华丽的分割线----------");
Field[] fields=c1.getDeclaredFields();
for(Field f:fields){
System.out.println(f.getName()+"~~"+f.getType()+"~~"+f.getModifiers()+"~~");//0代表的是protected
}
System.out.println("-----方法------");
Method methods[] = c1.getDeclaredMethods();
for (Method m:methods) {
System.out.println(m.getName()+"="+m.getReturnType());
}
System.out.println("-------调用方法的里面的东西 无参----------");
Method m= c1.getDeclaredMethod("study");
m.invoke(c1.newInstance(),null);
System.out.println("-------调用方法的里面的东西 有参----------");
Method m2 = c1.getDeclaredMethod("eat", String.class);
m2.invoke(c1.newInstance(),"汉堡包");
System.out.println("---------通过反射调用构造器-------------");
Constructor constructor = c1.getConstructor(String.class);
constructor.newInstance("小西");
Constructor[] constructors = c1.getConstructors();
for (Constructor con:constructors) {
System.out.println(con);
}
//正射
Student stu=new Student();
//反射得到对象 1.forName方法 需要处理异常
try {
//1.class.forname
Class c3=Class.forName("com.bdqn.reflectdemo.Student");
//指定包名。类名 加载出来的一个“类”
Field[] fieldses=c.getDeclaredFields();
for (Field f:fields){
System.out.println(f);
}
//forname的特点:它可以拿到类里所有的东西 比如说私有的都能拿到
//2.类名.class
System.out.println("-----类名.class------");
Class c5=Student.class;
String name = c2.getName();
System.out.println(name);
//3.对象.getClass
Class c6= stu.getClass();
try {
Object ob=c.newInstance();//通过这个类生成一个对象
Student s=(Student)ob;//因为反射生成的是object对象
s.study();
} catch (Exception e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}