ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java反射机制

2022-02-02 16:34:55  阅读:139  来源: 互联网

标签:反射 java System public println 机制 out Class 属性


watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAeG1oLXN4aC0xMzE0,size_20,color_FFFFFF,t_70,g_se,x_16Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。)语言的一个关键性质。

 

 

回到顶部

2、反射能做什么?   

  我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!

 

回到顶部

3、反射的具体实现

  下面是一个基本的类 Person

 

复制代码

 1 package com.ys.reflex;

 2 public class Person {

 3 //私有属性

 4 private String name = "Tom";

 5 //公有属性

 6 public int age = 18;

 7 //构造方法

 8 public Person() {    

 9 }

10 //私有方法

11 private void say(){

12 System.out.println("private say()...");

13 }

14 //公有方法

15 public void work(){

16 System.out.println("public work()...");

17 }

18 }

复制代码

①、得到 Class 的三种方式

 

复制代码

 1 //1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object

 2 // 类型的对象,而我不知道你具体是什么类,用这种方法

 3   Person p1 = new Person();

 4   Class c1 = p1.getClass();

 5         

 6 //2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高

 7 // 这说明任何一个类都有一个隐含的静态成员变量 class

 8   Class c2 = Person.class;

 9         

10 //3、通过 Class 对象的 forName() 静态方法来获取,用的最多,

11 // 但可能抛出 ClassNotFoundException 异常

12   Class c3 = Class.forName("com.ys.reflex.Person");

复制代码

需要注意的是:一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的 c1,c2,c3进行 equals 比较,发现都是true

 

②、通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等

 

查阅 API 可以看到 Class 有很多方法:

 

  getName():获得类的完整名字。

  getFields():获得类的public类型的属性。

  getDeclaredFields():获得类的所有属性。包括private 声明的和继承类

  getMethods():获得类的public类型的方法。

  getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类

  getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

  getConstructors():获得类的public类型的构造方法。

  getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

  newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

 

我们通过一个例子来综合演示上面的方法:

 

复制代码

 1 //获得类完整的名字

 2 String className = c2.getName();

 3 System.out.println(className);//输出com.ys.reflex.Person

 4         

 5 //获得类的public类型的属性。

 6 Field[] fields = c2.getFields();

 7 for(Field field : fields){

 8 System.out.println(field.getName());//age

 9 }

10         

11 //获得类的所有属性。包括私有的

12 Field [] allFields = c2.getDeclaredFields();

13 for(Field field : allFields){

14 System.out.println(field.getName());//name age

15 }

16         

17 //获得类的public类型的方法。这里包括 Object 类的一些方法

18 Method [] methods = c2.getMethods();

19 for(Method method : methods){

20 System.out.println(method.getName());//work waid equls toString hashCode等

21 }

22         

23 //获得类的所有方法。

24 Method [] allMethods = c2.getDeclaredMethods();

25 for(Method method : allMethods){

26 System.out.println(method.getName());//work say

27 }

28         

29 //获得指定的属性

30 Field f1 = c2.getField("age");

31 System.out.println(f1);

32 //获得指定的私有属性

33 Field f2 = c2.getDeclaredField("name");

34 //启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消

35 f2.setAccessible(true);

36 System.out.println(f2);

37                 

38 //创建这个类的一个对象

39 Object p2 = c2.newInstance();

40 //将 p2 对象的 f2 属性赋值为 Bob,f2 属性即为 私有属性 name

41 f2.set(p2,"Bob");

42 //使用反射机制可以打破封装性,导致了java对象的属性不安全。 

43 System.out.println(f2.get(p2)); //Bob

44         

45 //获取构造方法

46 Constructor [] constructors = c2.getConstructors();

47 for(Constructor constructor : constructors){

48 System.out.println(constructor.toString());//public com.ys.reflex.Person()

49 }

复制代码

回到顶部

4、根据反射获取父类属性

  父类 Parent.java

 

 View Code

  子类 Son.java

 

 View Code

  测试类:

 

 View Code

  通过执行上述代码,我们获得了父类的私有属性值,这里要注意的是直接通过反射获取子类的对象是不能得到父类的属性值的,必须根据反射获得的子类 Class 对象在调用 getSuperclass() 方法获取父类对象,然后在通过父类对象去获取父类的属性值。

标签:反射,java,System,public,println,机制,out,Class,属性
来源: https://blog.csdn.net/weixin_57763462/article/details/122770128

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有