A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© tomson_tang 中级黑马   /  2015-2-4 09:20  /  637 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在Java中,每个类被加载之后,系统会为该类生成一个对应的class对象,也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。通过该class对象就可以访问到jvm中的这个类。在Java程序中获得class对象通常有如下3种方式:
  • 使用class类的forName(String clazzName)静态方法,该方法需要传入字符串参数,该字符串参数的值是某个类的全限定类名(必须添加完整包名)
  • 调用某个类的class属性来获取该类对应的class对象。例如,Person.class将会返回Person类对应的class对象
  • 调用某个对象的getClass()方法。该方法是Java.lang.Object类中的一个方法,所以所有的java对象都可以调用该方法,该方法将会返回该对象所属类对应的class对象。

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

  • 代码更安全。程序在编译阶段就可以检查需要访问的class对象是否存在
  • 程序性能更好。因为这种方式无需调用方法,故性能更好

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

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

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

这里举几个例子

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

  • Constructor<T>  getConstructor(class<?>...parameterTypes):返回此Class对象对应类的指定public构造器
  • Constuctor<?> [ ] getConnstuctor():返回此class对象的所有public构造器
  • Constructor<T> getDeclaredConstructor(class<?>...parameterTypes):返回该class对象对应类指定的构造器,与构造器的访问权限无关
  • Constuctor<?>  [ ] getDeclaredConstructor():返回该class对象的全部构造器,与构造器的访问权限无关

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

  • Method getMethod(String name,class<?>...parameterTypes):返回此Class对象对应类的指定public方法
  • Method [ ] getMethod():返回此class对象的所有public方法
  • Method getDeclaredMethod(String name,class<?>...parameterTypes):返回该class对象对应类指定的方法,与方法的访问权限无关
  • Method [ ] getDeclaredMethod():返回该class对象的全部方法,与方法的访问权限无关

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

  • Filed getFiled(String name):返回此Class对象对应类的指定public Filed
  • Filed [ ] getFiled():返回此class对象的所有public Filed
  • Filed getDeclaredFiled(String name):返回该class对象对应类指定的 Filed,与 Filed的访问权限无关
  • Filed [ ] getDeclaredFiled():返回该class对象的全部 Filed,与 Filed的访问权限无关

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

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

  • public void info()
  • public void info(String str)
  • public void info(String str,Integer num)

这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. }
复制代码



结果为:

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马