首页 > 编程语言 >Java反射

Java反射

时间:2022-11-25 20:35:33浏览次数:33  
标签:反射 Java name System String println public out

反射:框架设计的灵魂,将类的各个组成部分封装为其他对象,这就是反射机制。

  反射的好处:

    1.可以在程序运行过程中,操作这些对象

    2.可以解耦,提高程序的可扩展性

框架:半成品软件。可以在框架的基础上进行软件开发,简化编码的动作。

 

Java代码在计算机中经历的三个阶段:

Source源代码阶段:.java 文件 ----> .class字节码文件

Class类对象阶段:类加载器ClassLoader将字节码文件加载进内存,在内存中,字节码文件由类Class的对象描述,Class对象中又包含类数组Field[] fields描述成员变量,类数组Constructor[] cons描述构造方法,类数组Method[] methods描述成员方法

Runtime运行时阶段:创建对象

将成员变量封装为Field对象,将构造方法封装为Constructor对象,将成员方法构造为Method对象就是反射的过程。

IDE中键盘打出一个对象会自动提示可用的方法就是用到了反射机制,在内存中已经将该对象所有的成员方法提取出来封装到Method数组中,在IDE中打出对象后自动提取出Method数组的内容并显示到列表中。

 

获取Class对象的方式:

  1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

    * 多用于配置文件,将类名定义在配置文件中,读取文件,加载类

  2. 类名.class:通过类名的属性class获取

    * 多用于参数的传递

  3. 对象.getClass():该方法在Object类中定义的,所有类都有该方法

    * 多用于已经存在对象时

 1 /* Person.java */
 2 
 3 public class Person {
 4     private String name = "name的默认值";
 5     private int age;
 6     public String test = "test的默认值";
 7 
 8     public Person() {}
 9 
10     public Person(String name, int age) {
11         this.name = name;
12         this.age = age;
13     }
14 
15     public String getName() {
16         return name;
17     }
18     public void setName(String name) {
19         this.name = name;
20     }
21 
22     public int getAge() {
23         return age;
24     }
25     public void setAge(int age) {
26         this.age = age;
27     }
28 
29     public void eat() {
30         System.out.println("吃了一口");
31     }
32 
33     public void eat(String food) {
34         System.out.println("吃了一口" + food);
35     }
36 
37     @Override
38     public String toString() {
39         return "Person {"
40                 + "name=" + name + ", "
41                 + "age=" + age + ", "
42                 + "test=" + test
43                 + "}";
44     }
45 }
 1 public class ReflectDemo_1 {
 2     public static void main(String[] args) throws Exception {
 3         // 1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
 4         Class cls1 = Class.forName("domain.Person");
 5         System.out.println(cls1);
 6 
 7         // 2. 类名.class:通过类名的属性class获取
 8         Class cls2 = Person.class;
 9         System.out.println(cls2);
10 
11         // 3. 对象.getClass():该方法在Object类中定义的,所有类都有该方法
12         Person person = new Person();
13         Class cls3 = person.getClass();
14         System.out.println(cls3);
15 
16         // 比较三个类
17         System.out.println(cls1 == cls2);
18         System.out.println(cls1 == cls3);
19         System.out.println(cls2 == cls3);
20     }
21 }

 

三个class对象相同,由此可知,同一个.class字节码文件在一次运行过程中只会被加载一次,无论通过哪一种方法获得的Class对象都是同一个

 

Class对象功能:

  1. 获取成员变量

    * Field[] getFields():获取所有public修饰的成员变量

    * Field[] getField(String name):获取所有指定名称的public修饰的成员变量

    * Field[] getDeclaredFields():获取所有成员变量,不考虑修饰符

    * Field[] getDeclaredField(String name):获取所有指定名称的成员变量,不考虑修饰符

    * setAccessible(true):忽略访问权限修饰符的安全检查,也叫暴力反射

    (之前学习类时说到私有成员无法在类外访问,但在反射这里没有私有公有的概念,但是要获得私有成员具体的值需要用到暴力反射

  2. 获取构造方法

    * Constructor<?>[] getConstructs()

    * Constructor<T> getConstruct(类<?>... parameterTypes)

    * Constructor<?>[] getDeclaredConstructs()

    * Constructor<T> getDeclaredConstruct(类<?>... parameterTypes)

  3. 获取成员方法

    * Method[] getMethods()

    * Method getMethod(String name, 类<?>... parameterTypes)

    * Method[] getDeclaredMethods()

    * Method getDeclaredMethod(String name, 类<?>... parameterTypes)

  4. 获取类名

    * String getName()

 

成员变量Field

  * 常见操作

    1. 获取值:get(Object obj)

    2. 设置值:void set(Object obj, Object value)

 1 public class ReflectDemo_2 {
 2     public static void main(String[] args) throws Exception {
 3         // 获取Person的Class对象
 4         Class personClass = Person.class;
 5 
 6         // 获取成员变量
 7         // * Field[] getFields():获取所有public修饰的成员变量
 8         Field[] fields = personClass.getFields();
 9         for(Field field : fields) {
10             System.out.println(field);
11         }
12         System.out.println("------------------------------------------");
13         // * Field[] getField(String name):获取所有指定名称的public修饰的成员变量
14         Field test = personClass.getField("test");
15         System.out.println(test);
16         // 获取成员变量test的值
17         Person p = new Person();
18         Object value_test1 = test.get(p);
19         System.out.println(value_test1);
20         // 设置成员变量test的值
21         test.set(p, "test更新后的值");
22         Object value_test2 = test.get(p);
23         System.out.println(value_test2);
24         System.out.println(p);
25         System.out.println("------------------------------------------");
26         // * Field[] getDeclaredFields()
27         Field[] declaredFields = personClass.getDeclaredFields();
28         for (Field declaredField : declaredFields) {
29             System.out.println(declaredField);
30         }
31         System.out.println("------------------------------------------");
32         // * Field[] getDeclaredField(String name)
33         Field name = personClass.getDeclaredField("name");
34         System.out.println(name);
35         // 忽略访问权限修饰符的安全检查,也叫暴力反射
36         name.setAccessible(true);
37         Object value_name1 = name.get(p);
38         System.out.println(value_name1);
39     }
40 }


构造方法Constructor

  * 常见操作

    创建对象:T newInstance(Object...initargs)

 1 public class ReflectDemo_3 {
 2     public static void main(String[] args) throws Exception {
 3         // 获取Person的class对象
 4         Class personClass = Person.class;
 5 
 6         // 获取构造方法
 7         // * Constructor<T> getConstruct(类<?>... parameterTypes)
 8         // 带参数的构造方法
 9         Constructor constructor = personClass.getConstructor(String.class, int.class);
10         System.out.println(constructor);
11         Object person = constructor.newInstance("zs", 15);
12         System.out.println(person);
13         System.out.println("------------------------------------------");
14         // 空构造方法
15         Constructor constructor_null = personClass.getConstructor();
16         Object person_null = constructor_null.newInstance();
17         System.out.println(person_null);
18         // 更简单的使用空构造函数的方法,但此方法已被弃用
19         Object obj = personClass.newInstance();
20         System.out.println(obj);
21     }
22 }

 

成员方法Method

  * 常见操作

    执行方法:Object invoke(Object obj, Object args)

  * 获取方法名

    String getName()

 1 public class ReflectDemo_4 {
 2     public static void main(String[] args) throws Exception {
 3         // 获取Person的class对象
 4         Class personClass = Person.class;
 5 
 6         // 获取指定名称的成员方法
 7         Method eat_method = personClass.getMethod("eat");
 8         Person p = new Person();
 9         eat_method.invoke(p);
10         Method eat_method_food = personClass.getMethod("eat", String.class);
11         eat_method_food.invoke(p, "饭");
12         System.out.println("------------------------------------------");
13         // 获取所有public修饰的方法
14         Method[] methods = personClass.getMethods();
15         for (Method method : methods) {
16             System.out.println(method);
17             // 获取方法名:getName()
18             System.out.println(method.getName());
19         }
20         // 获取类名:getName()
21         System.out.println(personClass.getName());
22     }
23 }

 

标签:反射,Java,name,System,String,println,public,out
From: https://www.cnblogs.com/yyyz888/p/16907496.html

相关文章

  • Java 中经常被提到的 SPI 到底是什么?
    layout:postcategories:Javatitle:Java中经常被提到的SPI到底是什么?tagline:by子悠tags:-子悠Java程序员在日常工作中经常会听到SPI,而且很多框架都使......
  • java基础语法学习笔记
    java基础语法学习笔记数组定义的三种方法int[]array1={1,2,3,4,5};//定义一int[]array2=newint[10];//定义二int[]array3=newint[]{1,2,3,4,5};/......
  • 第三周课程设计进展——基于java语言的国密算法库编译测试
    本周计划完成的任务本周实际完成情况(代码,文档,程序运行截图...),未完成计划的原因?如何改进?本周遇到的问题与解决过程(要详细)本周计划完成的任务给openeuler配置java......
  • 自学Java的基本态度
    面对Java学习,第一就是兴趣培养,第二基础打牢。学Java从入门到精通,需要家人们能一直保持学习的态度,特别如今技术更迭又快,这时就要我们多学想多看。只有Java知识不停学,家人们的......
  • java 接口限制访问次数
    1.通过注解的形式实现通用接口访问次数限制(1)pom.xml文件中引入expiringmap<dependency><groupId>net.jodah</groupId><artifactId>expiringmap</artifa......
  • JavaWeb知识总结
    HTML是什么:HyperTextMarkerLanguage超文本标记语言超文本:超级文本例如流媒体、声音、图片等标签:这种语言有大量的标签组成任何一个标签都有开始标签和结束标签开......
  • java学习笔记
    定义数组1.整形数组,charfloatdouble等和int格式相同int[]<数组名>=newint[needsize]; 2.定义字符串数组String<数组名>;<数组名>={"littleshark!"}; ......
  • java出现javax/xml/bind/DatatypeConverter错误
     今天在使用Jwt生成token的时候出现的错误,错误如下:Exceptioninthread"main"java.lang.NoClassDefFoundError:javax/xml/bind/DatatypeConverter atio.jsonwebtoken......
  • JAVA数据类型-占用字节
    数据类型 数值类型整数 byte占1个字节范围:-128~127 short占2个字节范围:-32768~32767 int占4个字节范围:-2147483648~2147483647 long占8个字节浮点 float占4个......
  • 资深java面试题及答案整理(四)
     资深java面试题及答案整理(四)7.编写Java程序时,如何在Java中创建死锁并修复它?经典但核心Java面试问题之一。如果你没有参与过多线程并发Java应用程序的编码,你......