OS:题外话,作为一个码龄三年的Java程序员,00后,算不得太优秀,平常自己学习笔记都在wolai上,也是时候加入CSDN大家族了,哈哈哈。咳咳,拙劣见解,学习笔记,广纳百川,凑合看吧。
框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
概念:将类的各个组成部分封装为其他对象,这个操作就是反射机制。
好处:可以在程序运行过程中,操作这些对象。可以解耦,提高程序可拓展性。
获取class对象的方式
1.Class.forName("全类名") ;将字节码文件加载进内存,返回class对象 (这种情况多用于配置文件,将类名定义在配置文件中。读取文件,加载类)
2.通过类名.class的方式获取 (多用于参数传递)
3.通过对象.getClass() 的方法获得对象(此方法定义在了object中,也就是所有的类都继承了这个方法。多用于通过对象获得字节码文件)
同一个字节码文件(*).class文件一次程序运行过程中只会被加载一次,所以无论通过以上哪种方法获得的class对象,都是同一对象。
class对象的功能
1.获取成员变量们
//返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。
//此方法只能获取指定名称的public修饰的成员变量
Field getField(String name)
//返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。
//此方法只能获取public修饰的成员变量
Field[] getFields()
//返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。
//这个获取指定名称的成员变量,不考虑修饰符
Field getDeclaredField(String name)
//返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。
//这个获取所有的成员变量,不考虑修饰符
Field[] getDeclaredFields()
/**
Field 对象的方法
*/
//返回该所表示的字段的值 Field ,指定的对象上。
Object get(Object obj)
//返回由此 Field对象表示的字段的名称。
String getName()
//将指定对象参数上的此 Field对象表示的字段设置为指定的新值。
void set(Object obj, Object value)
//通常情况下,私有的变量不可以被操作,但是可以通过field对象的setAccessable方法来实现暴力反射
Class studentClass = Student.class;
Field field = studentClass.getDeclaredField("studentName");
Student stu = new Student();//该类中定义了一个private studentName 字段
//field.setAccessable(true);//暴力反射(此方法忽略了访问修饰符的安全检查)
Object fieldObj = field.get(stu);
System.out.println(fieldObj);//这个操作会报异常。但是在此之前暴力反射的话,即可以访问和设值
2.获取构造方法们
//返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。
Constructor<T> getConstructor(类<?>... parameterTypes)
//返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。
Constructor<?>[] getConstructors()
//返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
//返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。
Constructor<?>[] getDeclaredConstructors()
/**
Constructor 对象的方法
*/
//使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。
T newInstance(Object... initargs)
//Student类中 private String studentName; private Integer age;
//定义了两个构造方法,一个无参,一个 String,Integer的有参,都为public类型
Class studentClass = Student.class;
//此方法获取无参构造方法
Constructor constructor_none = studentClass.getConstructor();
//此方法获取有参构造方法
Constructor constructor_have = studentClass.getConstructor(String.class,Integer.class);
//通过Constructor对象来创建对象
//获得一个stu1对象,其中studentName 和age都是没有值
Object stu1 = constructor_none.newInstance();
//获得一个stu2对象,其中studentName 和age分别为 张三和28岁
Object stu2 = constructor_have.newInstance("张三",28);
//如果Student类中的构造方法的访问修饰符是private的话
//那么就需要使用getDeclaredConstructor()方法,并且开启暴力反射
constructor_have.setAccessable(true);
3.获取成员方法们
//返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
Method getMethod(String name, 类<?>... parameterTypes)
//返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象
//包括那些由类或接口和那些从超类和超接口继承的声明。
//当使用clas对象的getMethods()方法时,他返回的不仅是当前类所有的public方法,以及继承父类的方法
//当一个类没有继承任何类,那么他默认继承了Object类,返回的数组里会有一些Object的方法,例如wait()..
Method [] getMethods()
//返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。
Method getDeclaredMethod(String name, 类<?>... parameterTypes)
//返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象
//包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
Method [] getDeclaredMethods()
/**
Method 对象的方法
*/
//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。
Object invoke(Object obj, Object... args)
//Student 类中定义了一个无参的public的study的方法和一个参数为String food的eat方法
Class studentClass = Student.class;
Method method_study = studentClass.getMethod("study");
Method method_eat = studentClass.getMethod("eat",String.class);
Student stu = new Student();
//study 是无参方法,传入对象即可执行
method_study.invoke(stu);//调用学习方法
//eat 是有参方法,传入对象之后需要给定实际参数
method_eat.invoke(stu,"西红柿炒鸡蛋");//嗲用吃东西方法,吃的食物为西红柿炒鸡蛋
//当然,如果eat方法或者study方法使用private修饰的,那么就要使用getDeclaredMethod(),并且暴力反射
//method_study.setAccessable(true);
//如果调用静态方法,那么这个invoke传入的对象写为null
4.获取包名类名等
//返回由 类对象表示的实体(类,接口,数组类,原始类型或空白)的名称,作为 String 。
String getName()
//获取此类的包。
Package getPackage()