java基础之反射

反射
一个Class实例包含了该class的所有完整信息:
在实例中保存了该class的所有信息,包括类名、包名、父类、
实现的接口、所有方法、字段等,因此,如果获取了某个Class实例,
我们就可以通过这个Class实例获取到该实例对应的class的所有信息
这种通过Class实例获取class信息的方法称为反射Reflection

   ┌───────────────────────────┐
 * │      Class Instance       
 * ├───────────────────────────┤
 * │name = "java.lang.String"  │
 * ├───────────────────────────┤
 * │package = "java.lang"      │
 * ├───────────────────────────┤
 * │super = "java.lang.Object" │
 * ├───────────────────────────┤
 * │interface = CharSequence...│
 * ├───────────────────────────┤
 * │field = value[],hash,...   │
 * ├───────────────────────────┤
 * │method = indexOf()...      │
 * └───────────────────────────┘
 */

1.获取class对象,三种方式

	静态变量class获取
	Class class = String.class;
	
	实例变量获取提供的getClass()方法获取
	User user = new User();
	Class class = user.getClass()
	
	Class的完整包路径名获取Class.forName()方法
	Class class = Class.forName("java.lang.String");
	
	获取该类中父类的class就不一样啦,下面这样就可以获取了
	Class  superClass = String.class.getSuerclass();

2.获取构造方法,创建新的实例

   通过反射创建新的实例,可以用Class提供的newInstance()方法
   but 它只能调用该类的public无参构造方法,有参和私有的构造你是无法通过	 他去创建实例的
   User user = User.class.newInstance();
   
   为了调用任意的构造方法,java的反射提供了Constructor对象
   Constructor<String> const =  String.class.getConstructor(String.class);
   通过它创建实例,并通过构造方法赋值
  String hello =  const.newInstance("hello");
  
  but构造方法私有后还是无法用上面的方式获取的,让后就有了暴力反射获取
  Constructor<User> userConst = User.class.getDeclaredConstructor(String.class,String.class);
  userConst.setAccessible(ture) //通过这一步设置允许进入访问,强制获取
  这一步很重要,没有设置私有构造你去获取就会报错
  User user = userConost.newInstance("username","password");
  好了现在我们就创建了对象并可以使用了
  user.username获取字段值

3.反射获取字段

还是上面说的获取到了对象的Class,就可以获取它的一切信息
我在User中定义的两个String类型的username和password字段
username是private修饰的而password是用public修饰的
Class<User> userClass = User.class;
//通过字段名去获取对应的字段信息
Filed password = userClass.getFiled("password")
输出如下public java.lang.String com.example.demo.reflected.User.password
//获取私字段名有字段
Filed username = userClass.getDeclaredFiled("username");
username中还可以获取很对信息,如type,name,Modifiers等这里就不一一列举了自己动手才是最容易理解的
//User继承了一个基础类Person类,那怎么获取父类中的字段呢,如下
获取父类中的私有id字段
Field declaredField = userClass.getSuperclass().getDeclaredField("id");
//获取所有私有字段字段,不包括父类
Field[] fields = aClass.getDeclaredFields(); 
//获取所有共有字段包括父类的
Field[] fields = aClass.getFields(); 

4.反射获取方法

Method getMethod(name, Class...):获取某个public的Method(包括父类)
获取有一个int参数的get方法
Method username = User.class.getMethod("getUsername",int.class);

Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
获取私有的String的get方法,第一个参数是方法名,第二个参数是方法入参类型
Method password = User.class.getDeclareMethod("getPassword",String.class);

获取没有参数的方法不用传入后面的参数类型,因为是无入参的
Method username = User.class.getMethod("print");

Method[] getMethods():获取所有public的Method(包括父类)
Method[] methods = p.getClass().getMethods();

Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
Method[] declaredMethods = p.getClass().getDeclaredMethods();

获取到方法当然最重要的是执行调用啦,我们用invoke方法
User user = User.class.newInstance();
Method method = User.class.getDeclareMethod("getPassword",String.class);
参数一是调用的对象,第二参数是该方法需要传入的对象
调用后是方法的返回值
Object  o = method.invoke(user,"123456");
这里要注意的是调用私有方法的时候要执行下面一步
Method.setAccessible(true)允许其调用这一步很重要

使用反射调用方法时,仍然遵循多态原则:即总是调用实际类型的覆写方(如果存在)

好了反射就到这里了其中还有很多内容需要自己去探索,反射对以后学习框架spring aop是很重要的good luck!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值