Java反射

1 获取Class(字节码)对象的方式

Class.foName("全类名");
类名.class
对象.getClass():getClass方法在Oject中定义着

编写Person类 Person.java

public class Person {

    private String name;
    private int age;

    public String a;
    protected String b;
    String c;
    private String d;

    public Person() {
        super();
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
	
    public void eat() {
        System.out.println("eat...");
    }
	
    public void eat(String food) {
        System.out.println("eat..." + food);
    }

}

编写获取字节码测试类ReflectDemo1.java

public class ReflectDemo1 {

    public static void main(String[] args) throws Exception {

        // 1.Class.foName("")
        Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");
        System.out.println(clazz);
        // 2类名.class
        Class<?> clazz1 = Person.class;
        System.out.println(clazz1);
        // 3对象.getClass()
        Person person = new Person();
        Class<? extends Person> clazz2 = person.getClass();
        System.out.println(clazz2);
		
        System.out.println(clazz==clazz1);
        System.out.println(clazz==clazz2);
        System.out.println(clazz2==clazz1);
		
        Class<?> clazz3 = Student.class;
        System.out.println(clazz3 == clazz);
		
    }

}

运行结果

结论:同一字节码文件在一次运行过程中,只会被加载一次,不论通过哪一种方式获得的Class对象都是同一个  

2 Class对象功能

获取功能

2.1获取成员变量们

Field getField(String name);//获取单个的public修饰的变量
Field[] getFields();//获取所有public修饰的变量
    
Field getDeclaredField(String name);//获取任意的变量
Field[] getDeclaredFields();//获取所有的变量,无关修饰符

setAccessible(true);//忽略访问权限修饰符的安全检查,暴力反射

 Filed成员变量

set(Object obj, Object value);//(1)设置值  
Object get(Object obj);(2)获取值

 

代码示例:

public void getFields() throws Exception {
    Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");

    // 获取所有的成员变量
    System.out.println("-----------------getFields");
    Field[] fields = clazz.getFields();
    Arrays.asList(fields).stream().forEach(System.out::println);

    System.out.println("-----------------getField");
    Field a = clazz.getField("a");
    System.out.println(a);
    // 获取成员变量a的值
    Person p = new Person();
    Object value = a.get(p);
    System.out.println(value);
    // 设置a的值
    a.set(p, "xxx");
    System.out.println(p);

    System.out.println("-----------------getDeclaredFields");

    Field[] fields2 = clazz.getDeclaredFields();
    Arrays.asList(fields2).stream().forEach(System.out::println);

    System.out.println("-----------------getDeclaredField");

    Field d = clazz.getDeclaredField("d");
    // 忽略访问权限修饰符的安全检查
    d.setAccessible(true);// 暴力反射
    System.out.println(d.get(p));

    System.out.println("-----------------");
}

 

2.2获取构造方法

Constructor<T> getConstructor(Class<?>... parameterTypes);
Constructor<?>[] getConstructors();

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);
Constructor<?>[] getDeclaredConstructors();

Constructor构造

T newInstance(Object... initargs);//创建对象
Class.newInstance();//;直接创建空参对象

代码示例:

 

public void getConstructors() throws Exception {

    Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");

    // Constructor<T> getConstructor(Class<?>... parameterTypes);
    System.out.println("----------getConstructor有参");
    Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
    System.out.println(constructor);
    // 创建对象
    Object person = constructor.newInstance("张三", 24);
    System.out.println(person);

    System.out.println("----------getConstructor空参");
    Constructor<?> constructor2 = clazz.getConstructor();
    Object person2 = constructor2.newInstance();
    System.out.println(person2);

    // 如果使用空参,那么操作是可以简化的
    Object person3 = clazz.newInstance();//
    System.out.println(person3);
}

2.3 获取成员方法

Method getMethod(String name, Class<?>... parameterTypes);
Method[] getMethods();

Method getDeclaredMethod(String name, Class<?>... parameterTypes);
Method[] getDeclaredMethods();

Method 方法

Object invoke(Object obj, Object... args);//执行方法
String getName();//获得方法名

代码示例:

public void getMethods() throws Exception {

    Class<?> clazz = Class.forName("com.tang.reflect.domain.Person");
    // 获得指定名称的方法
    System.out.println("-------------------getMethod");
    Method method = clazz.getMethod("eat");
    Object person = clazz.newInstance();
    Object invoke = method.invoke(person);
    System.out.println(invoke);

    Method method1 = clazz.getMethod("eat", String.class);
    Object invoke1 = method1.invoke(person, "饭");
    System.out.println(invoke1);

    // 获取所有public修饰的方法
    System.out.println("-------------------getMethods");
    Method[] methods = clazz.getMethods();
    Arrays.asList(methods).stream().forEach(e -> {
        e.setAccessible(true);//暴力反射
        System.out.println(e);
        System.out.println(e.getName());
    });
}

2.4 获取类名

String getName();

代码示例

public void getClazz() throws Exception {
    //获取类名
    String clazzName = clazz.getName();
    System.out.println(clazzName);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值