黑马程序员技术交流社区

标题: 个人总结之class类分析 [打印本页]

作者: tomson_tang    时间: 2015-2-4 09:20
标题: 个人总结之class类分析
在Java中,每个类被加载之后,系统会为该类生成一个对应的class对象,也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。通过该class对象就可以访问到jvm中的这个类。在Java程序中获得class对象通常有如下3种方式:

对于第一种方式和第二种方式都是直接根据类来取得该类的class对象,相比之下,第二种方式有如下两种优势:

也就是说,大部分时间我们都应该使用第二种方式来获取指定类的class对象。但如果我们只有一个字符串,例如“java.lang.String”(譬如在配置文件中取出数据来利用反射机制创建对象的情况),若需要获取该字符串对应的class对象,则只能使用第一种方式,使用class类的forName(String clazzName)静态方法获取class对象时该方法可能会抛出ClassNotFoundException异常

一旦获得了某个类所对应的class对象之后,程序就可以调用class对象的方法来获的该对象和该对象的真实信息。

class类提供了大量的实例方法来获取该class对象所对应类的详细信息:

这里举几个例子

下面4个方法用于获取class对应的类所包含的构造器:(不会返回父类的构造器)

下面4个方法用于获取class对象对应类所包含的方法:(会返回法雷的方法)

下面4个方法用于访问class对应类所包含的File

其他的方法可以查看class 类的api。

上面的多个getMethod()方法和getConstructor()方法中,都需要传入多个类型为Class<?>的参数,用于获取指定的方法或指定的构造器。关于这个参数的作用,假设某个类内包含如下3个info方法签名:

这3个同名方法属于重载,他们的方法名相同,但参数列表不同。在java语言中需要确定一个方法光有方法名是不行的,如果需要确定一个方法,则应该由方法名和形参列表来确定,但形参名没有实际意义,所以只能由形参类型来确定。例如,我们想要确定第二个info方法,则必须指定方法名为info,形参类表为String.class

clazz.getMethod("info",String.class)

想要获取第3个info方法,则可以:

clazz.getMethod("info",String.class,Integer.class)

获取构造器是无需传入构造器名,同一个类的所有构造器的名字是相同的,所以要确定一个构造器只要指定形参列表即可。

下面举个例子示范如何通过该class对象来获取对应类的详细信息:

  1. import java.lang.reflect.*;
  2. import java.lang.annotation.*;
  3. public class ClassTest
  4. {
  5. // 为该类定义一个私有的构造器
  6. private ClassTest()
  7. {
  8. }
  9. // 定义一个有参数的构造器
  10. public ClassTest(String name)
  11. {
  12.   System.out.println("执行有参数的构造器");
  13. }
  14. // 定义一个无参数的info方法
  15. public void info()
  16. {
  17.   System.out.println("执行无参数的info方法");
  18. }
  19. // 定义一个有参数的info方法
  20. public void info(String str)
  21. {
  22.   System.out.println("执行有参数的info方法"
  23.    + ",其str参数值:" + str);
  24. }
  25. // 定义一个测试用的内部类
  26. class Inner
  27. {
  28. }
  29. public static void main(String[] args)
  30.   throws Exception
  31. {
  32.   // 下面代码可以获取ClassTest对应的Class
  33.   Class<ClassTest> clazz = ClassTest.class;
  34.   // 获取该Class对象所对应类的全部构造器
  35.   Constructor[] ctors = clazz.getDeclaredConstructors();
  36.   System.out.println("ClassTest的全部构造器如下:");
  37.   for (Constructor c : ctors)
  38.   {
  39.    System.out.println(c);
  40.   }
  41.   // 获取该Class对象所对应类的全部public构造器
  42.   Constructor[] publicCtors = clazz.getConstructors();
  43.   System.out.println("ClassTest的全部public构造器如下:");
  44.   for (Constructor c : publicCtors)
  45.   {
  46.    System.out.println(c);
  47.   }
  48.   // 获取该Class对象所对应类的全部public方法
  49.   Method[] mtds = clazz.getMethods();
  50.   System.out.println("ClassTest的全部public方法如下:");
  51.   for (Method md : mtds)
  52.   {
  53.    System.out.println(md);
  54.   }
  55.   // 获取该Class对象所对应类的指定方法
  56.   System.out.println("ClassTest里带一个字符串参数的info方法为:"
  57.    + clazz.getMethod("info" , String.class));
  58.   // 获取该Class对象所对应类的上的全部注释
  59.   Annotation[] anns = clazz.getAnnotations();
  60.   System.out.println("ClassTest的全部Annotation如下:");
  61.   for (Annotation an : anns)
  62.   {
  63.    System.out.println(an);
  64.   }
  65.   System.out.println("该Class元素上的@SuppressWarnings注释为:"
  66.    + clazz.getAnnotation(SuppressWarnings.class));
  67.   System.out.println("ClassTest的包为:" + clazz.getPackage());
  68.   System.out.println("ClassTest的父类为:" + clazz.getSuperclass());
  69. }
  70. }
复制代码



结果为:






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2