反射

本文详细介绍了Java反射机制,通过ReflectionTest类展示了如何使用反射创建对象、访问私有属性和方法。讨论了反射与面向对象封装性的关系,并提供了获取Class实例的多种方式。此外,还提供了一个Person类作为反射操作的例子。
摘要由CSDN通过智能技术生成


总结于尚硅谷学习视频

代码

ReflectionTest类

package com.day0322_1;

import org.junit.jupiter.api.Test;

import java.lang.annotation.ElementType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionTest {

    //反射之前
    @Test
    public void test1(){

        //1.创建Person类的对象
        Person p1=new Person("Tom",12);

        //2.通过对象,调用其内部的属性、方法
        p1.age=10;
        System.out.println(p1.toString());

        p1.show();

        //在Person类外部,不可以通过Person类的对象来调用其内部私有的结构。
        //比如:name showNation 以及私有的构造器

    }

    //反射之后,对Person的操作

    @Test
    public void test2() throws Exception {
        Class clazz =Person.class;
        //通过反射,创建Person类的对象
        Constructor cons = clazz.getConstructor(String.class, int.class);
        Object obj = cons.newInstance("Tom", 12);
        Person p=(Person)obj;
        System.out.println(p.toString());
        //2.通过反射,调用对象的指定的方法、属性
        //调用属性
        Field age = clazz.getDeclaredField("age");
        age.set(p,10);
        System.out.println(p.toString());
        //调用方法
        Method show = clazz.getDeclaredMethod("show");
        show.invoke(p);
        System.out.println("*******************");
        //通过反射,可以调用Person类的私有结构。比如:私有的构造器,方法、属性
        //调用私有的构造器
        Constructor cons1 = clazz.getDeclaredConstructor(String.class);
        cons1.setAccessible(true);
        Person p1= (Person) cons1.newInstance("Jerry");
        System.out.println(p1);

        //调用私有的属性
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(p1,"HanMeimei");
        System.out.println(p1);

        //调用私有的方法
        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        String nation= (String) showNation.invoke(p1,"中国");//相当于p1.showNation("中国");
        System.out.println(nation);


    }

    //疑问:同过直接new的方式或反射的方式都可以调用公共的结构,开发中到底用哪个?
    //建议:直接new的方式。
    //什么时候会使用:反射的方式。  反射的特征:动态性
    //疑问:反射机制与面向对象的封装性是不是矛盾的?如何看待两个技术?
    //不矛盾。

    /*
    关于java.lang.Class类的理解
    1.类的加载过程:
    程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾),
    接着我们使用

    java.exe命令对某个字节码文件进行解释运行。相当于某个字节码文件加载到内存中。此
    就称为类的加载过程。加载到内存中的类,我们解称为运行时类,此
    运行时类,就称为Class的一个实例。

    2.换句话说,Class的实例对应着一个运行时类。
    3.加载到内存中的运行时类,会缓存一定的时间。在此时间内,我们可以通过不同的方式
    来获取此运行时类。



     */
    //获取Class的实例的方式(前三种掌握)
    @Test
    public void test3() throws Exception{
        //方式一:调用运行时类的属性
        Class clazz1=Person.class;//可用泛型
        System.out.println(clazz1);
        //方式二:通过运行时类的对象
        Person p1=new Person();
        Class clazz2 = p1.getClass();
        System.out.println(clazz2);

        //方式三:调用Class的静态方法:forName(String classPath)(多用)
        Class clazz3 = Class.forName("com.day0322_1.Person");
//        clazz3=Class.forName("java.lang.String");
        System.out.println(clazz3);

        System.out.println(clazz1==clazz2);//true
        System.out.println(clazz1==clazz3);//true

        //方式四:使用类的加载器:Classloader(了解)
        ClassLoader classLoader = ReflectionTest.class.getClassLoader();
        Class<?> clazz4 = classLoader.loadClass("com.day0322_1.Person");
        System.out.println(clazz4);

        System.out.println(clazz1==clazz4);


    }


    //万事万物皆对象?对象xxx,File,URL,反射,前端,数据库操作


    //Class实例可以使哪些结构的说明
    @Test
    public void test4(){
        Class c1=Object.class;
        Class c2=Comparable.class;
        Class c3=String.class;
        Class c4=int[][].class;
        Class c5= ElementType.class;
        Class c6=Override.class;
        Class c7=int.class;
        Class c8=void.class;
        Class c9=Class.class;

        int [] a=new int[10];
        int [] b=new int[100];
        Class c10 = a.getClass();
        Class c11 = b.getClass();

        //只要数组的元素类型与维度一样,就是同一个Class
        System.out.println(c10==c11);//true


    }

}

Person类

package com.day0322_1;

public class Person {

    private  String name;
    public   int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private Person(String name) {
        this.name = name;

    }

    private Person( int age) {

        this.age = age;
    }
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public void show(){
        System.out.println("你好,我是一个人");

    }

    private String showNation(String nation){
        System.out.println("我的国籍是"+nation);
        return nation;
    }



}

图片

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日星月云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值