Java高级--反射

1、什么是反射

反射是框架设计的灵魂。框架是一个半成品,可以在框架中加入自己的业务代码,提高开发效率。

反射就是把类中成员抽取成其他类的过程。

Java源码经历了三个阶段,源码阶段,字节码阶段,运行阶段

1、我们写好的Java源码文件,即.java 文件,通过javac命令,编译成字节码文件,即.class文件;

2、通过类加载器(ClassLoader)将存储在磁盘中的字节码文件加载到JVM内存中,在JVM内存中有一个反射类对象,将类中的属性存储在Field[] 中,将类中方法存储在Method[]中,这个反射类对象中除了我们自己写的类中的属性和方法还有反射类对象的自身的方法。

3、进入运行阶段,主方法中的对象,是从JVM内存中加载的。

2、获取反射类对象

第一种:通过Class.forName("全路径")获取反射对象

第二种:通过类名.class获取反射对象

第三种:通过对象.getClass()获取反射对象

public class People{
    private String name;
    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("My name is "+name);
    }
}


public class TestPeople {
    public static void main(String[] args) throws ClassNotFoundException {
        //1、根据Class.forName("全路径")获取People类的反射对象
        Class<?> aClass1 = Class.forName("test.People");
        //2、根据类名.class获取反射对象
        Class<People> aClass2 = People.class;
        People people = new People();
        //3、根据类对象.getClass()获取反射对象
        Class<? extends People> aClass3 = people.getClass();
        //三个反射对象的引用地址一致,一个类在JVM内存中被加载一次
        System.out.println(aClass1==aClass2);
        System.out.println(aClass1==aClass3);
    }
}

3、通过反射对象获取对应类的对象

aClass.newInstance();调用的是无参构造函数

public class TestPeople2 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        //1、获取类的反射类对象
        Class<People> aClass = People.class;
        //2、使用反射类对象创建类对象
        People people = aClass.newInstance();
        People people1 = aClass.newInstance();
        //3、通过反射类的newInstance()方法创建出的对象,引用地址不相等,该方法相当于调用了类的无参构造
        System.out.println(people==people1);
    }
}

4、通过反射获取相应的Field参数对象

1、getDeclaredField("属性名")   获取本类的属性对象,private,public,protected修饰的属性都可以拿到;

2、getDeclaredFields()   获取本类中所有的属性对象;

3、getField("属性名")   获取本类及父类中修饰符为public的指定的属性对象;

4、getFields()    获取本类及父类中所有修饰符为public的属性对象;

public class TestPeople3 {
    public static void main(String[] args) throws Exception {
        //1、获取反射对象
        Class<?> aClass = Class.forName("test.People");
        //2、通过反射对象获取本类中的属性对象,私有,共有和protected都可以拿到
        Field name = aClass.getDeclaredField("name");
        System.out.println(name);
        System.out.println("-------------------------------");
        //3、通过反射对象获取本类中所有的属性对象
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field);
        }
        System.out.println("-------------------------------");
        //4、通过反射类对象获取本类及父类中指定的修饰符为public的属性对象
        Field sex = aClass.getField("sex");
        System.out.println(sex);
        System.out.println("-------------------------------");
        //5、通过反射类对象获取本类及父类中所有修饰符为public的属性对象
        Field[] fields = aClass.getFields();
        for (Field field:fields) {
            System.out.println(field);
        }
    }
}

5、Field属性对象中常见的方法

1、getName()    获取属性对象的名称;

2、set(obj,value)    为obj对象的属性对象赋value值;

3、get(obj)    获取obj对象的属性对象的值;

4、setAccessible(true)   设置属性可访问;

public class TestPeople4 {
    public static void main(String[] args) throws Exception{
        Class<People> peopleClass = People.class;
        //1、获取属性对象
        Field nameField = peopleClass.getDeclaredField("name");
        //2、获取属性对象的名称
        String name = nameField.getName();
        System.out.println(name);
        People people = peopleClass.newInstance();
        System.out.println(people);
        //设置属性对象可访问
        nameField.setAccessible(true);
        //为某个对象的属性对象赋值
        nameField.set(people,"张三");
        System.out.println(people);
        //获取某个对象的属性对象的值
        Object o = nameField.get(people);
        System.out.println(o);
    }
}

6、通过反射获取对应的Method方法对象

1、getDeclaredMethods()      获取本类中的所有的反射方法对象;

2、getMethods()    获取本类和父类中修饰符为public的方法对象;

3、getDeclaredMethod("方法名", Class<?> 参数类型)   获取本类中指定的方法对象;

4、getMethod("方法名", Class<?> 参数类型)   获取本类及父类中修饰符为public的指定的方法对象

public class TestPeople5 {
    public static void main(String[] args) throws NoSuchMethodException {
        Class<People> peopleClass = People.class;
        //获取本类中的反射方法对象
        Method[] declaredMethods = peopleClass.getDeclaredMethods();
        for (Method method : declaredMethods){
            System.out.println(method);
        }
        System.out.println("----------------------------------");
        //获取本类和父类中修饰符为public的方法对象
        Method[] methods = peopleClass.getMethods();
        for (Method method:methods){
            System.out.println(method);
        }
        System.out.println("----------------------------------");
        //获取本类中的指定方法对象
        Method setName = peopleClass.getDeclaredMethod("setName", String.class);
        System.out.println(setName);
        System.out.println("----------------------------------");
        //获取本类及父类中修饰符为public的方法对象
        Method equals = peopleClass.getMethod("equals", Object.class);
        System.out.println(equals);
    }
}

7、Method方法对象中常见的方法

invoke(对象,方法参数值)    回调对象中的某个方法

public class TestPeople6 {
    public static void main(String[] args) throws Exception {
        Class<People> peopleClass = People.class;
        //获取本类的方法对象
        Method setName = peopleClass.getDeclaredMethod("setName", String.class);
        People people = peopleClass.newInstance();
        //回调people对象的setName方法
        setName.invoke(people,"张三");
        System.out.println(people);
    }
}

8、获取相应注解对象

getAnnotation(注解名.class)     获取注解对象

getAnnotations()     获取所有注解对象

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
public @interface MyAnnotation {
    String value();
}


@MyAnnotation("type")
public class Person {
    @MyAnnotation("field")
    private String username;

    @MyAnnotation("method")
    public void show(){
        System.out.println(username);
    }
}


public class TestAnnotation {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Class<Person> personClass = Person.class;
        //1、获取类对象的注解对象
        MyAnnotation annotation = personClass.getAnnotation(MyAnnotation.class);
        System.out.println(annotation.value());

        //2、获取属性对象上的注解对象
        Field username = personClass.getDeclaredField("username");
        MyAnnotation annotation1 = username.getAnnotation(MyAnnotation.class);
        System.out.println(annotation1.value());

        //3、获取方法对象上的注解对象
        Method show = personClass.getDeclaredMethod("show");
        MyAnnotation annotation2 = show.getAnnotation(MyAnnotation.class);
        System.out.println(annotation2.value());
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值