Java开发:反射机制

news2024/11/15 6:55:18

一、Java Reflection

Reflection(反射)是java被视为动态语言的关键(Java是静态语言,因为有了反射所以又被成为“准动态语言”)

二、重点:一个类只有一个Class对象

三、反射的优缺点

优点:可以实现动态创建对象和编译,体现出很大的灵活性
缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。
这类操作总是慢于 直接执行相同的操作。

四、获取Class类的实例

1、该方法最安全可靠,性能最高。
Class c1 = Student.class;
2、通过类的实例获取Class对象
Person student = new Student(“学生”);
Class c2 = student.getClass();
3、通过类名全路径获取Class对象
Class c3 = Class.forName(“com.baidu.baike.lesson.annotations_reflection.Student”);

public class RLesson002 {
    public static void main(String[] args) {
        try {
            Person student = new Student("学生");
            System.out.println(student.name);

            //推荐使用1
            Class c1 = Student.class;

            Class c2 = student.getClass();

            //推荐使用2
            Class c3 = Class.forName("com.baidu.baike.lesson.annotations_reflection.Student");

            //可以获取父类的class
            Class superclass = c1.getSuperclass();

            //c1、c2、c3的hashCode相同
            System.out.println(c1.hashCode());
            System.out.println(c2.hashCode());
            System.out.println(c3.hashCode());
            System.out.println(superclass);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }


    }
}

class Person {
    public String name;

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

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

class Student extends Person {

    public Student(String name) {
        super(name);
    }
}


五、几乎所有类型都有class对象

class:外部类,成员(成员内部类、静态内部类),局部内部类,匿名内部类
interface:接口
[]:数组
enum:枚举
annotation:注解@interface
primitive type:基本数据类型
void:方法


public class RLesson003 {
    public static void main(String[] args) {
        Class c1 = Object.class;//类
        Class c2 = Comparable.class;//接口
        Class c3 = String[].class;//一维数组
        Class c4 = int[][].class;//二维数组
        Class c5 = Override.class;//注解
        Class c6 = ElementType.class;//枚举
        Class c7 = Integer.class;//基本数据类型
        Class c8 = void.class;//方法
        Class c9 = Class.class;//Class

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

    }

}

六、类加载内存分析


public class RLesson002 {
    public static void main(String[] args) {

        System.out.println(Person.m);
        Person p1 = new Person("小明");
    }
}

class Person {
    static {
        System.out.println("Person类的静态代码块初始化");
        m = 300;
    }

    static int m = 100;
    public String name;

    public Person(String name) {
        System.out.println("Person类的无参构造初始化");
        this.name = name;
    }
}

运行结果:
Person类的静态代码块初始化
100
Person类的无参构造初始化

Process finished with exit code 0

七、获取类的运行时结构


public class RLesson004 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("com.baidu.baike.lesson.annotations_reflection.User");
        //获取类的名字
        System.out.println(c1.getName());//获取包名+类名
        System.out.println(c1.getSimpleName());//获取类型

        System.out.println("==========获取类的属性===========");
        System.out.println("------>获取public的属性");
        Field[] fields = c1.getFields();//获取public的属性
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("------>获取private+public的属性");
        fields = c1.getDeclaredFields();//获取private+public的属性
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("==========获取指定属性的值===========");
        Field fName = c1.getDeclaredField("name");
        System.out.println(fName);

        System.out.println("==========获取类的方法===========");
        System.out.println("------>获取public的方法");
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println("public的方法" + method);
        }
        System.out.println("------>获取自定义的public+private方法");
        methods = c1.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("public+private的方法 -> " + method);
        }

        System.out.println("==========获取指定方法===========");
        Method getName = c1.getMethod("getName");
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

        System.out.println("==========获取构造器===========");
        System.out.println("-----------获取public的构造器");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("-----------获取private+public的构造器");
        constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        System.out.println("==========获取指定构造器===========");
        Constructor mConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        System.out.println(mConstructor);
    }
}

class User {
    private String name;
    private int age;
    public int sex;

    public User() {
    }

    private User(String name) {
        this.name = name;
    }

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

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

    private int getSex() {
        return sex;
    }

    private void setSex(int sex) {
        this.sex = sex;
    }
}

运行结果:
com.baidu.baike.lesson.annotations_reflection.User
User
==========获取类的属性===========
------>获取public的属性
public int com.baidu.baike.lesson.annotations_reflection.User.sex
------>获取private+public的属性
private java.lang.String com.baidu.baike.lesson.annotations_reflection.User.name
private int com.baidu.baike.lesson.annotations_reflection.User.age
public int com.baidu.baike.lesson.annotations_reflection.User.sex
==========获取指定属性的值===========
private java.lang.String com.baidu.baike.lesson.annotations_reflection.User.name
==========获取类的方法===========
------>获取public的方法
public的方法public java.lang.String com.baidu.baike.lesson.annotations_reflection.User.getName()
public的方法public void com.baidu.baike.lesson.annotations_reflection.User.setName(java.lang.String)
public的方法public int com.baidu.baike.lesson.annotations_reflection.User.getAge()
public的方法public void com.baidu.baike.lesson.annotations_reflection.User.setAge(int)
public的方法public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public的方法public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public的方法public final void java.lang.Object.wait() throws java.lang.InterruptedException
public的方法public boolean java.lang.Object.equals(java.lang.Object)
public的方法public java.lang.String java.lang.Object.toString()
public的方法public native int java.lang.Object.hashCode()
public的方法public final native java.lang.Class java.lang.Object.getClass()
public的方法public final native void java.lang.Object.notify()
public的方法public final native void java.lang.Object.notifyAll()
------>获取自定义的public+private方法
public+private的方法 -> public java.lang.String com.baidu.baike.lesson.annotations_reflection.User.getName()
public+private的方法 -> public void com.baidu.baike.lesson.annotations_reflection.User.setName(java.lang.String)
public+private的方法 -> public int com.baidu.baike.lesson.annotations_reflection.User.getAge()
public+private的方法 -> public void com.baidu.baike.lesson.annotations_reflection.User.setAge(int)
public+private的方法 -> private int com.baidu.baike.lesson.annotations_reflection.User.getSex()
public+private的方法 -> private void com.baidu.baike.lesson.annotations_reflection.User.setSex(int)
==========获取指定方法===========
public java.lang.String com.baidu.baike.lesson.annotations_reflection.User.getName()
public void com.baidu.baike.lesson.annotations_reflection.User.setName(java.lang.String)
==========获取构造器===========
-----------获取public的构造器
public com.baidu.baike.lesson.annotations_reflection.User(java.lang.String,int,int)
public com.baidu.baike.lesson.annotations_reflection.User()
-----------获取private+public的构造器
public com.baidu.baike.lesson.annotations_reflection.User(java.lang.String,int,int)
private com.baidu.baike.lesson.annotations_reflection.User(java.lang.String)
public com.baidu.baike.lesson.annotations_reflection.User()
==========获取指定构造器===========
public com.baidu.baike.lesson.annotations_reflection.User(java.lang.String,int,int)

八、动态创建对象

A、创建类的对象

调用Class对象的newInstance()方法。

  • 类必须有一个无参数的构造器
  • 类的构造器的访问权限需要足够

B、具体步骤

  • 通过Class类的getDeclaredConstructor(Class …parameterTypes)取得本类的指定形参类型的构造器。
  • 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数
  • 通过Constructor实例化对象

C、示例代码

public class RLesson005 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class c1 = Class.forName("com.baidu.baike.lesson.annotations_reflection.User");

        //使用默认无参构造
        User user = (User) c1.newInstance();
        user.setName("小花");
        user.setAge(18);
        //获取private方法并赋值
        Method setSex = c1.getDeclaredMethod("setSex", int.class);
        //不能直接操作私有方法,将私有方法设为可见
        setSex.setAccessible(true);
        setSex.invoke(user, 2);
        System.out.println(user);


        //使用三个参数的构造器
        Constructor mConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
         user = (User) mConstructor.newInstance("小王", 10, 8);
         //获取私有属性
        Field name = c1.getDeclaredField("name");
        //不能直接操作私有属性,将私有属性设为可见
        name.setAccessible(true);
        name.set(user, "小赵");
        System.out.println(user);
    }
}

class User {
    private String name;
    private int age;
    public int sex;

    public User() {
    }

    private User(String name) {
        this.name = name;
    }

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

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

    private int getSex() {
        return sex;
    }

    private void setSex(int sex) {
        this.sex = sex;
    }

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


执行结果:
User{name='小花', age=18, sex=2}
User{name='小赵', age=10, sex=8}

九、获取注解信息

A、应用场景

利用注解和反射完成类和表结构的映射关系
在这里插入图片描述

B、示例代码


public class ALesson002 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("com.baidu.baike.lesson.annotations_reflection.StudentAL2");
        Annotation[] c1_annotation = c1.getDeclaredAnnotations();
        for (Annotation annotation : c1_annotation) {
            System.out.println(annotation);
        }
        System.out.println("======================");
        Field field_name = c1.getDeclaredField("name");
        FieldName field_nameDeclaredAnnotation = field_name.getDeclaredAnnotation(FieldName.class);
        System.out.println(field_nameDeclaredAnnotation.columnName() + ",type->" + field_nameDeclaredAnnotation.type() + ",length->" + field_nameDeclaredAnnotation.length());
    }
}

@TableName("studeng_al2")
class StudentAL2 {
    @FieldName(columnName = "f_name", type = "1", length = 10)
    private String name;
    @FieldName(columnName = "f_age", type = "2", length = 3)
    private int age;
    @FieldName(columnName = "f_sex", type = "3", length = 2)
    private int sex;
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableName {
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldName {
    String columnName();

    String type();

    int length();
}

运行结果:
@com.baidu.baike.lesson.annotations_reflection.TableName(value=studeng_al2)
======================
f_name,type->1,length->10

结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/67986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVA问题解决方案】02.Freemarker导出Excel超出上限分表解决方案

陈老老老板🦸👨‍💻本文专栏:Java问题解决方案(都是一些常见的问题解决方案)👨‍💻本文简述:本文讲一下有关Freemarker导出Excel分表的解决方案,超级详细。&a…

Tomcat7+ 弱口令 后台getshell漏洞

Tomcat7 弱口令 && 后台getshell漏洞 🍉 shell 此环境来自vulhub工程: https://github.com/vulhub/vulhub 以下测试环境为ubuntu 20.04 🍉目录Tomcat7 弱口令 && 后台getshell漏洞环境准备弱密码登录war文件上传蚁剑连接…

SoftEther linux与windows使用

1、SoftEther简介 我们来先科普一下什么是SoftEther吧,SoftEther是由日本筑波大学的登大遊在硕士论文中提出的开源、跨平台、多重协议的虚拟专用网方案,其实我更看重的是他的内网穿透功能,下面来一张图片,说明它的强大。 SoftEther正确定的安…

【力扣】剑指offer第二天

剑指offer第二天[剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode)]方法一代码方法二代码[剑指 Offer 24. 反转链表 - 力扣(LeetCode)]方法一代码方法二代码[剑指 Offer 35. 复杂链表的复制 - 力扣(LeetCode&#xf…

日期功能组件(加上左右点击,更改月份)

要求效果&#xff1a; &#xff0c;直接可以显示年月&#xff0c;并且点击左右箭头可以更改月份 点击这个日期&#xff0c;可以选择。 最后实现效果&#xff1a; 实现&#xff1a; 先找一个插件&#xff0c;可以选择时间 <!-- 选择年月--><div class"form-…

SAP ARFCSTATE ARFCSDATA TRFCQOUT

SELECT count(1) FROM arfcsstate --18848155 20221122 清理前 -- 6582457 清理后 SELECT count(1) FROM ARFCSDATA a -- 81732430 202221122 清理前 -- 25064628 清理后 SELECT count(1) FROM TRFCQOUT t --18848095 202221122 …

面试必备:HashMap底层源码原来是这么简单(分析)

微信公众号&#xff1a;SteveCode 关注可了解更多的编程及开发经验。问题或建议&#xff0c;请公众号留言; 专注Java技术干货分享&#xff0c;Java技术、数据结构、相关工具、Spring全家桶、intellij idea…… 如果你觉得对你有帮助&#xff0c;欢迎赞赏 transient 发现了这个关…

re:Invent现场访谈:云计算如何重塑智能制造

众所周知&#xff0c;近年来包括中国和美国在内&#xff0c;世界上各个主要国家对制造业的关注度都在不断提升。也正因为如此&#xff0c;在2022亚马逊云科技re:Invent全球大会上&#xff0c;有关云计算技术在智能制造行业的应用&#xff0c;也理所当然地成为了诸多与会嘉宾关注…

【JMeter】线程组jp@gc - Stepping Thread Group(逐步线程组)

jpgc - Stepping Thread Group 逐步线程组 Action to be taken after a Sample error 发生sample错误时 Continue 继续 Start Next Thread Loop 开始新的线程 Stop Thread 停止线程 Stop Test 停止测试 Stop Test Now 立即停止测试 Threads Scheduling Parameters 线程调度…

STM32+雷龙SD NAND(贴片SD卡)完成FATFS文件系统移植与测试

一、前言 在STM32项目开发中&#xff0c;经常会用到存储芯片存储数据。 比如&#xff1a;关机时保存机器运行过程中的状态数据&#xff0c;上电再从存储芯片里读取数据恢复&#xff1b;在存储芯片里也会存放很多资源文件。比如&#xff0c;开机音乐&#xff0c;界面上的菜单图…

使用SpringBoot快速构建Web API

Dubbo 框架现在在国内的中小企业当中已经成为 Java 生态下服务化的事实标准&#xff0c;出现这种状态的原因很多&#xff0c;比如 Dubbo 框架设计优秀、文档和资料丰富、配置灵活、特性丰富等&#xff0c;但最主要的&#xff0c;我认为是 Java 开发人员对速度这一因素的痴迷。 …

详解设计模式:解释器模式

解释器模式&#xff08;interpreter pattern&#xff09;&#xff0c;是在 GoF 23 种设计模式中定义了的行为型模式。 解释器模式 这种模式被用在 SQL 解析、符号处理引擎等。 解释器模式 给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xf…

HTTP状态码是什么?

文章目录HTTP状态码1. 消息&#xff1a;1xx2. 成功&#xff1a;2xx3. 重定向&#xff1a;3xx4. 请求错误&#xff1a;4xx5. 服务器错误&#xff1a;5xxHTTP状态码 HTTP 状态码&#xff08;HTTP Status Code&#xff09;是一个表示服务器响应状态的 3 位整数代码。比如当服务器…

[Database] 关系型数据库中的MVCC是什么?怎么理解?原理是什么?MySQL是如何实现的?

文章目录前言并发控制并发控制的实现与锁的本质MVCC是什么&#xff1f;MVCC的多版本&#xff08;Multi-Version&#xff09;指的是什么&#xff1f;MVCC的实现方式&#xff1f;MySQL的实现PostgreSQL的实现结语前言 在并发场景下&#xff0c;如果我们不对数据做保护&#xff0c…

分布式文件存储系统FastDFS[1]-介绍以及安装

一、分布式文件存储 1.分布式文件存储的由来 在我们的项目中有很多需要存储的内容出现&#xff0c;比如图片&#xff0c;视频&#xff0c;文件等等&#xff0c;在早期的时候用户量不大&#xff0c;产生的文件也不是很多&#xff0c;这时我们可以把文件和服务程序放在一个服务器…

STAAD.Pro CONNECT Edition

STAAD.Pro CONNECT Edition Bentley STAAD或STAAD Pro软件是分析和设计世界第三世界的第一款最佳工程软件&#xff0c;对于金属、混凝土、木材、铝和冷金属的专业选择&#xff0c;设计几乎所有类型的塑料、石化、隧道、桥梁、蜡烛等结构专业的功能和软件中任何数据大小的使用。…

Java课程案例学习(3)

2.1 学生管理系统实现步骤 案例需求 针对目前我们的所学内容&#xff0c;完成一个综合案例&#xff1a;学生管理系统&#xff01;该系统主要功能如下&#xff1a; 添加学生&#xff1a;通过键盘录入学生信息&#xff0c;添加到集合中 删除学生&#xff1a;通过键盘录入要删…

Jcmd 虚拟机诊断利器

Jcmd 虚拟机诊断利器 Java虚拟机&#xff08;JVM&#xff09;是运行Java程序的抽象化的计算器。今天&#xff0c;来学习下如何轻松诊断正在运行的JVM。 JDK本身中提供了许多可用的工具&#xff0c;可以用于各种开发、监视和故障排除活动。推荐使用jcmd&#xff0c;简单易懂&a…

[附源码]计算机毕业设计南通大学福利发放管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ThinkPHP6综合业务管理系统

有需要请私信或看评论链接哦 可远程调试 ThinkPHP6综合业务管理系统一 介绍 综合业务管理系统基于ThinkPHP6开发&#xff0c;数据库mysql&#xff0c;前端Layui&#xff0c;后台模板ok-admin。管理员登录系统后可对场所&#xff0c;分类&#xff0c;用户&#xff0c;运营商&am…