反射

简介: 反射

总结于尚硅谷学习视频

代码

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;
    }
}

图片





相关文章
解决element-ui上传多张图片时闪动问题
解决element-ui上传多张图片时闪动问题
728 0
|
移动开发 前端开发 JavaScript
惊!这些前端技术竟然能让你的网站在移动端大放异彩!
随着互联网技术的发展,移动设备成为主要的上网工具。本文介绍了几种关键的前端技术,包括响应式设计、图片优化、字体选择、HTML5和CSS3的应用、性能优化及手势操作设计,帮助开发者提升网站在移动端的显示效果和用户体验。示例代码展示了如何实现简单的双向绑定功能。
241 3
|
SQL 监控 关系型数据库
面试题MySQL问题之主从复制的数据一致性问题如何解决
面试题MySQL问题之主从复制的数据一致性问题如何解决
209 1
|
Ubuntu Linux
修改服务器名称
修改服务器名称
361 0
|
网络协议
网络层有哪些常见协议
网络层有哪些常见协议
|
数据采集 分布式计算 DataWorks
DataWorks产品使用合集之任务工作流中遇到了日志信息显示参数值没有正确解析的问题,该如何处理
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
缓存 Dart 监控
现代化 Android 开发:Jetpack Compose 最佳实践
如果一直关注 `Compose` 的发展的话,可以明显感受到 2022 年和 2023 年的 `Compose` 使用讨论的声音已经完全不一样了, 2022 年还多是观望,2023 年就有很多团队开始采纳 `Compose` 来进行开发了。不过也有很多同学接触了下 `Compose`,然后就放弃了。要么使用起来贼特么不顺手,要么就是感觉性能不行,卡。其实,问题只是大家的思维没有转换过来,还不会写 `Compose`。
697 1
|
存储 SQL 缓存
基于springboot+jpa 实现多租户动态切换多数据源 - 数据隔离方案选择分库还是分表
基于springboot+jpa 实现多租户动态切换多数据源 - 数据隔离方案选择分库还是分表
570 0
基于springboot+jpa 实现多租户动态切换多数据源 - 数据隔离方案选择分库还是分表
【数据结构】堆的建立 (时间复杂度计算-堆排序)---超细致
【数据结构】堆的建立 (时间复杂度计算-堆排序)---超细致
773 0
|
前端开发 大数据 关系型数据库
一次做数据报表的踩坑经历,让我领略了数据同步增量和全量的区别
嗨喽,大家好,我是创作新人,新时代新的农民工小赵,在今年的七月结束了大学生活,目前在一家大数据公司做开发。对于初入职场的同学来说,在实际的工作开发中会遇到各种各样问题,将问题沉淀、输出、总结,才会让后面的路走的越来越轻松。那么,接下来我会通过以下几个方面进行分享。
一次做数据报表的踩坑经历,让我领略了数据同步增量和全量的区别