Java反射机制

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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值