• 初级程序员必会的java反射教程


    目录

     🍏1. 创建一个Person实体类🍏

    🍎 2. 反射获取Class类对象的三种方法🍎

    🍎 2.1 通过全类名的方式获取

    🍎 2.2 类名.class

    🍎 2.3 实例对象.getClass() 

    🍎 2.4 总结

     🍒 3. 反射获取属性变量 🍒

    🍒 3.1 获取所有public修饰符的成员变量

    🍒 3.2 获取指定字段并赋值

     🍒 3.3 获取所有的成员变量(不考虑修饰符)

    🍒 3.4 获取私有的变量(利用暴力反射)

    🍔 4.反射获取构造方法 🍔

     🍔 4.1有参构造

    🍔 4.2无参构造

     🍔 4.3无参构造简便写法

    🍓 5.反射获取成员方法 🍓

     🍓 5.1无参方法     

     🍓 5.2 有参方法

     🍓 5.3 获取所有方法(包含Object的方法)

    项目源码下载地址 : https://download.csdn.net/download/qq_45481709/86708493


     🍏1. 创建一个Person实体类🍏

    在后续的反射演示中我们都会拿Person类中的类名, 属性, 方法做演示

    1. package com.learning.java.fanshe.domain;
    2. import lombok.Data;
    3. /**
    4. * 拓展 :
    5. * 1.构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名)
    6. * 2.每个类可以有一个以上的构造器
    7. * 3.构造器可以有0个、1个或1个以上的参数
    8. * 4.构造器没有返回值
    9. * 5.构造器总是伴随着new操作一起调用
    10. */
    11. @Data
    12. public class Person {
    13. private String name;
    14. private Integer age;
    15. public String sex;
    16. public Person() {
    17. }
    18. public Person(String name, Integer age) {
    19. this.name = name;
    20. this.age = age;
    21. }
    22. public void walk() {
    23. System.out.println("我在走路");
    24. }
    25. public void walk(String name) {
    26. System.out.println(name + "在走路");
    27. }
    28. private void a() {
    29. }
    30. }

    🍎 2. 反射获取Class类对象的三种方法🍎

    🍎 2.1 通过全类名的方式获取

    1. Class a = Class.forName("com.learning.java.fanshe.domain.Person");
    2. System.out.println(a);

    首先这里的全类名可以理解为类的包路径

    Class.forName的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
    1. 输出结果 : 
    2. class com.learning.java.fanshe.domain.Person

    🍎 2.2 类名.class

    1. Class b = Person.class;
    2. System.out.println(b);

    用Class.类名的方法, jvm把类加载进内存但不进行初始化,返回Class对象

    1. 输出结果 : 
    2. class com.learning.java.fanshe.domain.Person

    🍎 2.3 实例对象.getClass() 

    1. Classextends Person> c = new Person().getClass();
    2. System.out.println(c);

    对类进行静态初始化、非静态初始化,返回引用是运行时真正所指对象(向上转型)所属类的Class对象

    1. 输出结果 : 
    2. class com.learning.java.fanshe.domain.Person

    🍎 2.4 总结

    在完成上面三种获取class类对象后, 不难发现最后输出的结果是一样的, 这里我们再用代码证实一下

    1. public static void main(String[] args) throws Exception {
    2. Class a = Class.forName("com.learning.java.fanshe.domain.Person");
    3. System.out.println(a);
    4. Class b = Person.class;
    5. System.out.println(b);
    6. Classextends Person> c = new Person().getClass();
    7. System.out.println(c);
    8. System.out.println(a == b);
    9. System.out.println(b == c);
    10. }
    1. 输出结果 : 
    2. true
    3. true

    结论:

    同一个字节码文件(*,c1ass)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个

     🍒 3. 反射获取属性变量 🍒

    🍒 3.1 获取所有public修饰符的成员变量

    1. Class persionClass = Person.class;
    2. Field[] fields = persionClass.getFields();
    3. for (Field field : fields) {
    4. //注: 这里只能获取public修饰的变量
    5. System.out.println(field);
    6. }
    1. 输出结果:
    2. public java.lang.String com.learning.java.fanshe.domain.Person.sex

    🍒 3.2 获取指定字段并赋值

    1. Field sex = persionClass.getField("sex");
    2. //获取成员变量sex的值
    3. Person person = new Person();
    4. //设置a的值
    5. sex.set(person, "张安");
    6. Object o = sex.get(person);
    7. System.out.println(o);
    1. 输出结果:
    2. 张安

     🍒 3.3 获取所有的成员变量(不考虑修饰符)

    1. for (Field declaredField : persionClass.getDeclaredFields()) {
    2. System.out.println(declaredField);
    3. }
    1. 输出结果:
    2. private java.lang.String com.learning.java.fanshe.domain.Person.name
    3. private java.lang.Integer com.learning.java.fanshe.domain.Person.age
    4. public java.lang.String com.learning.java.fanshe.domain.Person.sex

    🍒 3.4 获取私有的变量(利用暴力反射)

    之前我们的属性name是私有属性 private String name 如果想获取就需要暴力setAccessible(true)

    1. //获取私有的变量
    2. Field name = persionClass.getDeclaredField("name");
    3. //忽略访问权限修饰符的安全检查(暴力反射)
    4. name.setAccessible(true);
    5. Object o1 = name.get(person);
    6. System.out.println(o1);

     这里因为并未给该变量赋值所以输出为null

    1. 输出结果:
    2. null


    🍔 4.反射获取构造方法 🍔

     🍔 4.1有参构造

    1. //创建有参
    2. Constructor constructor = persionClass.getConstructor(String.class, Integer.class);
    3. System.out.println(constructor);
    4. //创建对象
    5. Person person1 = constructor.newInstance("张三", 12);
    6. System.out.println(person1);
    1. 输出结果:
    2. public com.learning.java.fanshe.domain.Person(java.lang.String,java.lang.Integer)
    3. Person(name=张三, age=12, sex=null)

    🍔 4.2无参构造

    1. //创建无参构造
    2. Constructor constructor1 = persionClass.getConstructor();
    3. System.out.println(constructor1);
    4. //创建对象
    5. Person person2 = constructor1.newInstance();
    6. System.out.println(person2);
    1. 输出结果:
    2. public com.learning.java.fanshe.domain.Person()
    3. Person(name=null, age=null, sex=null)

     🍔 4.3无参构造简便写法

    1. //无参构造的简便写法
    2. Person person3 = persionClass.newInstance();
    3. System.out.println(person3);
    1. 输出结果:
    2. Person(name=null, age=null, sex=null)

    🍓 5.反射获取成员方法 🍓

     🍓 5.1无参方法     

    1. Method walk = persionClass.getMethod("walk");
    2. Person person4 = new Person();
    3. //执行方法
    4. walk.invoke(person4);
    1. 输出结果:
    2. 我在走路

     🍓 5.2 有参方法

    1. Method walk1 = persionClass.getMethod("walk", String.class);
    2. walk1.invoke(person4,"张三");
    1. 输出结果:
    2. 张三在走路

     🍓 5.3 获取所有方法(包含Object的方法)

    1. Method[] methods = persionClass.getMethods();
    2. for (Method method : methods) {
    3. method.setAccessible(true);
    4. //获取方法名称
    5. System.out.println(method.getName());
    6. System.out.println(method);
    7. }
    1. equals
    2. public boolean com.learning.java.fanshe.domain.Person.equals(java.lang.Object)
    3. toString
    4. public java.lang.String com.learning.java.fanshe.domain.Person.toString()
    5. hashCode
    6. public int com.learning.java.fanshe.domain.Person.hashCode()
    7. getName
    8. public java.lang.String com.learning.java.fanshe.domain.Person.getName()
    9. setName
    10. public void com.learning.java.fanshe.domain.Person.setName(java.lang.String)
    11. walk
    12. public void com.learning.java.fanshe.domain.Person.walk()
    13. walk
    14. public void com.learning.java.fanshe.domain.Person.walk(java.lang.String)
    15. getAge
    16. public java.lang.Integer com.learning.java.fanshe.domain.Person.getAge()
    17. setAge
    18. public void com.learning.java.fanshe.domain.Person.setAge(java.lang.Integer)
    19. setSex
    20. public void com.learning.java.fanshe.domain.Person.setSex(java.lang.String)
    21. getSex
    22. public java.lang.String com.learning.java.fanshe.domain.Person.getSex()
    23. wait
    24. public final void java.lang.Object.wait() throws java.lang.InterruptedException
    25. wait
    26. public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    27. wait
    28. public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    29. getClass
    30. public final native java.lang.Class java.lang.Object.getClass()
    31. notify
    32. public final native void java.lang.Object.notify()
    33. notifyAll
    34. public final native void java.lang.Object.notifyAll()
    35. 我在走路

  • 相关阅读:
    向量的运算
    图文验证码怎么测试及自动化测试怎么解决验证码问题?
    LetCode刷题[简单题](3)检测最长公共字符串(排序的妙用)
    Python 实现微信测试号情侣纪念消息推送(消息群发)
    汇川PLC编程软件AutoShop的使用
    【最详细demo】雪花算法详细解释
    【17】c++设计模式——>原型模式
    雅思口语同替高分表达
    Java微服务+分布式+全栈项目(一)---->项目介绍+MyBatis-Plus入门
    流畅的Python读书笔记(四)序列:序列的运算及陷阱
  • 原文地址:https://blog.csdn.net/qq_45481709/article/details/127011901