Java反射机制概述与部分示例

一、定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

二、作用

在日常的开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法

三、反射机制相关类与方法

类名作用
Class类代表类的实体,在运行的Java应用程序中表示类和接口
Field类代表类的成员变量(成员变量也称为类的属性)
Method类代表类的方法
Constructor类代表类的构造方法
Class类

Class代表类的实体,在运行的Java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。

  • 获得类的相关方法
方法作用
asSubclass(Class clazz)把传递的类的对象转换成代表其子类的对象
Cast把对象转换成代表类或是接口的对象
getClassLoader()获得类的加载器
getClasses()返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses()返回一个数组,数组中包含该类中所有类和接口类的对象
getName()获得类的完整路径名字
forName(String className)根据类名返回类的对象
newInstance()创建类的实例
getPackage()获得类的包
getSimpleName()获得类的名字
getSuperclass()获得当前类继承的父类的名字
getInterfaces()获得当前类实现的类或是接口
1.常用获取Class对象实例的方法

a.已知具体类,如已知Person类,通过类的class属性获得,该方法最为安全可靠

Class clazz=Person.class;

b.已知某个类的实例,如person实例,调用该实例的getClass()方法获取Class对象

Class clazz= person.getClass();

c.已知某个类的全类名,且该类在类路径下,通过Class类的静态方法forName()获取,需抛出异常

Class clazz= Class.forName("com.ori.Person");

Type属性

基本类型都有type属性,可以得到这个基本类型的类型,比如:

Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Float.TYPE;
Class c4 = Double.TYPE;
2.获取类的成员

设定一个测试类


public class Test {
 
    private int age;
    private String name;
    private int testint;
 
    public Test(int age) {
        this.age = age;
    }
 
    public Test(int age, String name) {
        this.age = age;
        this.name = name;
    }
 
    private Test(String name) {
        this.name = name;
    }
 
    public Test() {
    }

2-1.获取类的所有构造方法


 Test test = new Test();
 Class c4 = test.getClass();
 Constructor[] constructors = c4.getDeclaredConstructors();
  • 通过getDeclaredConstructors可以返回类的所有构造方法,返回的是一个数组因为构造方法可能不止一个
  • 通过getModifiers可以得到构造方法的类型
  • getParameterTypes可以得到构造方法的所有参数,返回的是一个Class数组
  • 通过getConstructors方法获取类中 所有的public类型的构造方法
for (int i = 0; i < constructors.length; i++) {
        System.out.print(Modifier.toString(constructors[i].getModifiers()) + "参数:");
        Class[] parametertypes = constructors[i].getParameterTypes();
        for (int j = 0; j < parametertypes.length; j++) {
             System.out.print(parametertypes[j].getName() + " ");
       }
      System.out.println("");
  }

输出结果
在这里插入图片描述

2-2.调用构造方法
为了方便,对Test类中的构造器加上打印方法

  public Test(int age, String name) {
        this.age = age;
        this.name = name;
        System.out.println("hello" + name + "i am" + age);
    }
 
 
    private Test(String name) {
        this.name = name;
        System.out.println("My Name is" +
                name);
    }

借助于newInstance方法来得到类的实例

Class[] p = {int.class,String.class};
constructors = c4.getDeclaredConstructor(p);
constructors.newInstance(24,"HuangLinqing");

调用私有构造方法呢,和上面一样,只是我们要设置constructors.setAccessible(true);代码如下:

Class[] p = {String.class};
constructors = c4.getDeclaredConstructor(p);
constructors.setAccessible(true);
constructors.newInstance("HuangLinqing");

输出分别如下
在这里插入图片描述
在这里插入图片描述

2-3.调用类的私有方法
写一个私有方法在测试类里

  private void welcome(String tips){
        System.out.println(tips);
    }
  • 调用私有方法也需要得到类的实例,如之前的 c4
  • 首先通过 getDeclaredMethod方法获取到这个私有方法,第一个参数是方法名,第二个参数是参数类型
  • 然后通过invoke方法执行,invoke需要两个参数一个是类的实例,一个是方法参数
 Class[] p4 = {String.class};
     Method method = c4.getDeclaredMethod("welcome",p4);
     method.setAccessible(true);
     Object arg1s[] = {"My Name is HuangLinqing"};
     method.invoke(test,arg1s);

输出
在这里插入图片描述

2-4. 获取类的私有字段并修改值

Field类常用方法

方法用途
equals(Object obj)属性与obj相等则返回true
get(Object obj)获得obj中对应的属性值
set(Object obj, Object value)设置obj中对应属性值

在通过反射得到类的实例之后先获取字段:

Field field = c4.getDeclaredField("name");
field.setAccessible(true);
field.set(ref,"代码男人");

其中ref是通过反射构造方法获取的实例,打印field.get(ref).toString()的值如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值