java--反射(一)

举报
brucexiaogui 发表于 2021/12/29 23:57:52 2021/12/29
【摘要】 java--反射(一) 一、反射    元数据(MetaData) 描述数据结构的结构;反射就是得到元数据的行为。 二、反射引入   Object obj = new Student(); 若程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,但程序又需要调用该对象运行类型的方法:...

java--反射(一)

一、反射

   元数据(MetaData) 描述数据结构的结构;反射就是得到元数据的行为。

二、反射引入

 

  • Object obj = new Student();

若程序运行时接收到外部传入的一个对象,该对象的编译类型是Object,但程序又需要调用该对象运行类型的方法:
1.若编译和运行类型都知道,使用 instanceof判断后,强转。
2.编译时根本无法预知该对象属于什么类,程序只能依靠运行时信息来发现对象的真实信息,这时就必须使用反射了。

3.要是想得到对象真正的类型,就得使用反射。

三、Class类和Class类实例

 

  • Java程序中的各个Java类属于同一类事物,描述这类事物的Java类就是Class类。
  • 对比提问:众多的人用一个什么类表示?众多的Java类用一个什么类表示?

 

人   Person

 

Java类    Class

 

 

  • 对比提问: Person类代表人,它的实例对象就是张三,李四这样一个个具体的人,Class类代表Java类,它的各个实例对象又分别对应什么呢?

 

 

  1. 对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等;
  2. 一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的;
  3. 一个类在虚拟机中只有一份字节码;

 

 

四、获得Class对象

 

  • 如何得到各个字节码对应的实例对象?
  • 每个类被加载后,系统会为该类生成对应的Class对象,通过Class对象可以访问到JVM中的这个类,3种方式:

 

 

 

  1. 使用Class类的forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;
  2. 调用某个类的class属性获取Class对象,如Date.class会返回Date类对应的Class对象(其实就是得到一个类的一份字节码文件);
  3. 调用某个对象的getClass()方法。该方法属于Object类;

 

 

Class<?> clz = new Date().getClass();

 

 

获取对象实例


  
  1. package reflect;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. import java.util.List;
  5. import java.util.Map;
  6. enum Gender{
  7. MAN,WOMAN(),NONE{};
  8. }
  9. class User{
  10. }
  11. /**
  12. * 得到Class对象的三种方式:
  13. *
  14. * 1. 通过类的class属性;
  15. * 类.class;
  16. *、 2. 使用Class.forName(String className);className表示 一个类的全限定名
  17. *
  18. * Class clz = Class.forName("java.util.Date");
  19. * 此时 clz 就在描述 java.util.Date这个类
  20. *
  21. * 3. 通过对象的一个 getClass()方法可以搞定
  22. * Class<?> getClass() 返回此 Object 的运行时类。
  23. *
  24. */
  25. public class ClassDemo {
  26. String name;
  27. public static void main(String[] args) throws Exception {
  28. //得到Usre的字节码
  29. Class<User> clz = User.class;
  30. Class<User> clz2 = reflect.User.class;
  31. System.out.println(clz == clz2);
  32. String className = "java.util.Date";
  33. /**
  34. * public static Class<?> forName(String className)
  35. *
  36. *
  37. * Class<?> clz = Class.forName("java.lang.String");
  38. */
  39. Class<?> clz3 = Class.forName(className);
  40. Class<Date> clzDate = (Class<Date>) clz3;
  41. System.out.println(clzDate);
  42. System.out.println(clz == Class.forName("reflect.User"));//true
  43. List l = new ArrayList();
  44. Class<?> clzList = l.getClass();
  45. //现在获得l的真实类型
  46. System.out.println(l.getClass());//java.util.ArrayList
  47. //得到对象的真正类型
  48. /**
  49. * enum Gender{
  50. MAN,WOMAN(),NONE{};
  51. }
  52. */
  53. System.out.println("Gender.MAN= "+Gender.MAN.getClass());//reflect.Gender
  54. System.out.println("Gender.WOMAN= "+Gender.WOMAN.getClass());//reflect.Gender
  55. System.out.println("Gender.NONE= "+Gender.NONE.getClass());//reflect.Gender$1
  56. System.out.println(Map.class);
  57. }
  58. }

 

文章来源: brucelong.blog.csdn.net,作者:Bruce小鬼,版权归原作者所有,如需转载,请联系作者。

原文链接:brucelong.blog.csdn.net/article/details/80104580

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。