IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 妖怪,看法宝-----------------------------看反射的“照妖镜”如何让类原形毕露 -> 正文阅读

[Java知识库]妖怪,看法宝-----------------------------看反射的“照妖镜”如何让类原形毕露

反射

定义

反射机制是在运行状态中,对于任何一个类可以知道其所有的属性和方法(包括私有的),对于任何一个对象可以调用其所有的属性和方法(包括私有的),同时可以修改部分类型信息

反射起源

在这里插入图片描述

反射相关的类

类名用途
Class代表类的实体
Field代表类的成员变量
Method代表类的方法
Constructor代表类的构造方法
class Person{
    private String name = "James";
    public int age = 36;

    public Person() {
        this.name = "Kobe";
        this.age = 41;
    }

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

    private void BasketBall(){
        System.out.println("Rusall Westbrook");
    }
    public void Swimming(){
        System.out.println("Sun Yang");
    }

    private void FootBall(String str){
        System.out.println(str);
    }

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

获得Class类的对象

  • Class.forName("类的全路径名 (包名.类名) ")
    forName()是Class类的静态方法,此方法可能会抛出异常
  • 每一个类都有一个隐含的静态成员变量.class
  • 使用类的普通方法getClass()(继承自Object)
    先new一个类的对象,再调用getClass()方法
  • 一个类只能对应一个Class类对象
    public static void main(String[] args) {
        //1. 
        Class c1 = null;
        try{
            c1 = Class.forName("Reflect.Person");
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //2.
        Class c2 = Person.class;

        //3.
        Person person = new Person();
        Class c3 = person.getClass();

        System.out.println(c1 == c2);   //true
        System.out.println(c2 == c3);   //true
    }

创建对象

    public static void reflectnewInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class c = Class.forName("Reflect.Person");

        //调用Person的无参数构造方法,私有不可以(非私有的都可以)
        Person person = (Person) c.newInstance();

        System.out.println(person);  //Kobe 41
    }

反射私有的构造方法

getDeclaredConstructor(参数类型…)

方法用法
Constructor getConstructor(Class…<?> types)获取参数对应的公有构造方法
Constructor getDeclaredConstructor(Class…<?> types)获取参数对应的构造方法(公有、私有都可以哦)
Constructor[ ] getConstructors()获取该类的所有的公有构造方法
Constructor[ ] getDeclaredConstructors()获取该类所有的构造方法
    public static void re_Pri_Con() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class c = Class.forName("Reflect.Person");
        //通过参数,指定返回某个特定的私有构造方法
        Constructor constructor = c.getDeclaredConstructor(String.class,int.class);
        //设置权限
        constructor.setAccessible(true);
        //调用指定的构造方法
        Person person = (Person) constructor.newInstance("强爷",18);

        System.out.println(person); //强爷 18
    }
    public static void re_Pub_Con() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class c = Class.forName("Reflect.Person");
        Constructor constructor = c.getConstructor();
        constructor.setAccessible(true);
        Person person = (Person)constructor.newInstance();
        System.out.println(person);  //Kebo 41
    }

在这里插入图片描述

反射私有的成员变量

getDeclaredField(“指定成员变量的名字”)
field.set(类的对象,修改的成员变量的内容);

方法
Field getField(String name)获取对应的公有成员变量
Field getDeclaredField(String name)获取对应的成员变量(公有、私有)
Field[ ] getFields()获取所有的公有成员变量
Field[ ] getDeclaredFields()获取所有的成员变量
    public static void re_Pri_Field() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class c = Class.forName("Reflect.Person");
        Person person = (Person) c.newInstance();
        //getDeclareField()的参数是需要获取的私有变量的名字
        Field field = c.getDeclaredField("name");
        field.setAccessible(true);
        //修改对象的私有变量
        field.set(person,"Durant");
        System.out.println(person);  //Durant 41
        
        String str = (String) field.get(person);
        System.out.println("将私有属性修改为" + str);
    }

反射私有的方法

getDeclaredMethod(“指定方法的名字”,参数类型…)
invoke(类的对象,传入的参数)

方法
Method getMethod(String name, Class…<?> types)获取指定的公有方法
Method getDeclaredMethod(String name, Class…<?> types)获取指定的方法(公有、私有)
Method[ ] getMethods()获取所有的公有方法
Method[ ] getDeclaredMethods()获取所有的方法
    public static void re_Pri_Method() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
    
        Class c = Class.forName("Reflect.Person");
        Person person = (Person) c.newInstance();
        Method method = c.getDeclaredMethod("FootBall", String.class);
        method.setAccessible(true);
        method.invoke(person,"罗那尔多");

    }

反射的优点:

  • 对于任何一个类,可以直到它所有的属性和方法;对于任何一个对象可以调用它所有的属性和方法
  • 增减程序的灵活性
  • 反射已经应用于多个框架,Struts、Spring等

缺点

  • 使用反射导致程序效率降低
  • 反射绕过了源代码的技术,会带来维护问题

祝贺EDG3:2战胜DK登顶世界之巅
银龙重铸之日,骑士归来之时
重铸LPL荣光,我辈义不容辞
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:20:29  更:2021-11-09 19:20:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:14:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码