java.lang.Class类详解

java Class类详解

一、class类

  Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时系统(JVM)对所有对象进行运行时类型标识,即Class对象,JVM可以通过该对象操作相应的类(如选准正确的方法执行)。

  Class类用于封装被装入JVM中类(类或接口)的信息(类名、类型属于class、interface、enum还是annotation),是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息。

  在程序运行时,如果需要生成某个对象,这时JVM首先检测这个类的Class对象是否已经加载(关于类 的加载会咋后面讲到),如果没有,JVM就会根据文件名查找.class文件将其载入,用于创建所需要的实例。JVM为每个类管理一个独一无二的Class对象(前提使用了同一个类加载器)。

  基本数据类型(boolean、byte、char、short、int、long、float 和 double)和关键字void也对应一个Class对象。另外,每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

  Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。

1、获取某个类对应的Class对象的三种方法

  要想对JVM中Class对象封装的类信息进行访问,首先的获取对应类的Class对象,我们可以通过以下三种方式实现:

  a、通过Object的getClass()方法获取(所有的java对象都具备这个方法)

  b、使用.class的方式(使用类名加“.class”的方式即会返回与该类对应的Class对象,不需要创建该类的对象)

  c、使用Class.forName()方法,该方法据类名(字符串,包括类所在的包,如com.baidu.User)获取与该类关联的Class对象。

  下面是一段代码示例:

  1. public class ObtainClass {
  2.  
  3. public static void main(String[] args) {
  4. try {
  5. String str1 = "abc";
  6. System.out.println("通过Object的getClass()方法获取 : " + str1.getClass());
  7. System.out.println("使用.class的方式获取 : " + String.class);
  8. System.out.println("使用Class.forName()方法获取 : " + Class.forName("java.lang.String"));
  9. System.out.println(str1.getClass() == String.class);
  10. System.out.println(str1.getClass() == Class.forName("java.lang.String"));
  11. } catch (ClassNotFoundException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15.  
  16. }

  由上面代码可以看出,每个类都对应唯一的Class对象。

2、Class类的常用方法

  1. public class ClassTest {
  2. public static void main(String[] args) {
  3. try {
  4. System.out.println("返回与带有给定字符串名的类或接口相关联的 Class 对象 : " + Class.forName("com.classTest.classload.CTest"));
  5. System.out.println("以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称 : " + Class.forName("com.classTest.classload.CTest").getName());
  6. System.out.println("获取此类的包 : " + Class.forName("com.classTest.classload.CTest").getPackage());
  7. System.out.println("使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象 : " + Class.forName("com.classTest.classload.CTest", true, ClassLoader.getSystemClassLoader()));
  8. System.out.println("返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class : " + Class.forName("com.classTest.classload.CTest").getSuperclass());
  9. System.out.println("返回源代码中给出的底层类的简称 : " + Class.forName("com.classTest.classload.CTest").getSimpleName());
  10. System.out.println("获取此类的标记 : " + Class.forName("com.classTest.classload.CTest").getSigners());
  11.  
  12. CTest ct = new CTest();
  13. System.out.println("如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null : " + ct.annotationType());
  14. System.out.println("返回 Java Language Specification 中所定义的底层类的规范化名称 : " + Class.forName("com.classTest.classload.CTest").getCanonicalName());
  15. System.out.println("返回一个包含某些 Class 对象的数组,这些对象表示属于此 Class 对象所表示的类的成员的所有公共类和接口 : " + Class.forName("com.classTest.classload.CTest").getClasses());
  16. System.out.println("返回该类的类加载器 : " + Class.forName("com.classTest.classload.CTest").getClassLoader());
  17. System.out.println("返回表示数组组件类型的 Class : " + Class.forName("com.classTest.classload.CTest").getComponentType());
  18.  
  19. System.out.println("返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法 : " + Class.forName("com.classTest.classload.CTest"));
  20. System.out.println("返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法 : " + Class.forName("com.classTest.classload.CTest").getConstructors().length);
  21.  
  22. System.out.println("返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 : " + Class.forName("com.classTest.classload.CTest").getDeclaredField("age").getName());
  23. System.out.println("返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段 : " + Class.forName("com.classTest.classload.CTest").getDeclaredFields().length);
  24. System.out.println("返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 : " + Class.forName("com.classTest.classload.CTest").getField("str"));
  25. System.out.println("返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段 : " + Class.forName("com.classTest.classload.CTest").getFields().length);
  26.  
  27. System.out.println("返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法 : " + Class.forName("com.classTest.classload.CTest").getDeclaredMethod("annotationType").getName());
  28. System.out.println("返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法 : " + Class.forName("com.classTest.classload.CTest").getDeclaredMethods().length);
  29. System.out.println("如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法 : " + Class.forName("com.classTest.classload.CTest").getEnclosingMethod());
  30. System.out.println("返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法 : " + Class.forName("com.classTest.classload.CTest").getMethod("annotationType"));
  31. System.out.println("返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法 : " + Class.forName("com.classTest.classload.CTest").getMethods().length);
  32.  
  33. System.out.println("返回此类或接口以整数编码的 Java 语言修饰符 : " + Class.forName("com.classTest.classload.CTest").getModifiers());
  34.  
  35. System.out.println("如果此 Class 对象表示一个注释类型则返回 true : " + Class.forName("com.classTest.classload.ETest").isAnnotation());
  36. System.out.println("当且仅当底层类是匿名类时返回 true : " + Class.forName("com.classTest.classload.ETest").isAnonymousClass());
  37. System.out.println("判定此 Class 对象是否表示一个数组类 : " + Class.forName("com.classTest.classload.ETest").isArray());
  38. System.out.println("判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口 : " + Class.forName("com.classTest.classload.ETest").isAssignableFrom(Class.forName("com.classTest.classload.ETest")));
  39. System.out.println("当且仅当该类声明为源代码中的枚举时返回 true : " + Class.forName("com.classTest.classload.ETest").isEnum());
  40. System.out.println("判定指定的 Object 是否与此 Class 所表示的对象赋值兼容 : " + Class.forName("com.classTest.classload.CTest").isInstance(Class.forName("com.classTest.classload.CTest").newInstance()));
  41. System.out.println("判定指定的 Class 对象是否表示一个接口类型 : " + Class.forName("com.classTest.classload.CTest").isInterface());
  42. System.out.println("当且仅当底层类是本地类时返回 true : " + Class.forName("com.classTest.classload.CTest").isLocalClass());
  43. System.out.println("当且仅当底层类是成员类时返回 true : " + Class.forName("com.classTest.classload.CTest").isMemberClass());
  44. System.out.println("判定指定的 Class 对象是否表示一个基本类型 : " + Class.forName("com.classTest.classload.CTest").isPrimitive());
  45. System.out.println("如果此类是复合类,则返回 true,否则 false : " + Class.forName("com.classTest.classload.CTest").isSynthetic());
  46. System.out.println("创建此 Class 对象所表示的类的一个新实例 : " + Class.forName("com.classTest.classload.CTest").newInstance().toString());
  47. } catch (ClassNotFoundException e) {
  48. e.printStackTrace();
  49. } catch (NoSuchFieldException e) {
  50. e.printStackTrace();
  51. } catch (NoSuchMethodException e) {
  52. e.printStackTrace();
  53. } catch (InstantiationException e) {
  54. e.printStackTrace();
  55. } catch (IllegalAccessException e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. }
  60.  
  61. class CTest implements Annotation{
  62. private int age;
  63. private String name;
  64. public String str;
  65.  
  66. public Class<? extends Annotation> annotationType() {
  67. return CTest.class;
  68. }
  69.  
  70. @Override
  71. public String toString() {
  72. return "CTest{" +
  73. "age=" + age +
  74. ", name='" + name + '\'' +
  75. ", str='" + str + '\'' +
  76. '}';
  77. }
  78. }
  79.  
  80. enum ETest{
  81. CN,
  82. EN
  83. }

二、Method类

  Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。

  1. public class MethodTest {
  2.  
  3. public static void main(String[] args) throws Exception {
  4. Class clazz = Class.forName("com.classTest.classload.MT");
  5. Method[] m = clazz.getMethods();
  6. for (Method mh : m) {
  7. System.out.print(mh.getName() + " | " + mh.getDefaultValue() + " | " + mh.getReturnType());
  8. Class[] c = mh.getParameterTypes();
  9. System.out.print(" | len = " + c.length + " | ");
  10. for (Class tv : c) {
  11. System.out.print(" " + tv.getName());
  12. }
  13. System.out.println();
  14. }
  15.  
  16. Method method = clazz.getMethod("mt", String.class);
  17. method.invoke(clazz.newInstance(), "test method");// 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法
  18. }
  19.  
  20. }
  21.  
  22. class MT {
  23. public String mt(String str) {
  24. System.out.println(str);
  25. return str;
  26. }
  27. }

三、Field类

  Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。

  1. public class FieldTest {
  2.  
  3. public static void main(String[] args) throws Exception {
  4. Class clazz = Class.forName("com.classTest.classload.FT");
  5. Field[] f = clazz.getFields();
  6. for(Field fd : f) {
  7. System.out.println(fd.getName() + " | " + fd.getType() + " | " + fd.getModifiers() + " | " + fd.get(""));
  8. }
  9.  
  10. }
  11.  
  12. }
  13.  
  14. class FT{
  15. public static String name = "name";
  16. public static int age = 11;
  17. }

java基础知识(十一)java反射机制(上)的更多相关文章

  1. Java开发培训基础知识解析之反射机制

    Java是老牌编程语言,是当前应用最广泛的编程语言之一.想要学习Java你就一定要掌握Java基础知识,而反射对于初学Java的人来说绝对是非常重要的知识点.什么是反射?如何理解反射机制?如何使用反射 ...

  2. java 基础知识三 java变量

    java  基础知识 三 变量 1.作用域 {} 包围起来的代码 称之为代码块,在块中声明的变量只能在块中使用 2.常量 就是固定不变的量,一旦被定义,它的值就不能再被改变. 3.变量 变量必须在程序 ...

  3. Java基础(十一)——反射

    一.概述 1.介绍 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法. 加载完类 ...

  4. JAVA基础知识之JVM-——使用反射生成并操作对象

    Class对象可以获取类里的方法,由Method对象表示,调用Method的invoke可以执行对应的方法:可以获取构造器,由Constructor对象表示,调用Constructor对象的newIn ...

  5. 《Java基础知识》Java 反射详解

    定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射 ...

  6. Java基础系列 - 泛型和反射机制

    package com.test5; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Java泛型和反射机 ...

  7. 《Java基础知识》Java注解"@"详解

    Java注解含义: Java注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的.Java注解又叫java标注,java提供了一套机制,使得 ...

  8. 《Java基础知识》Java异常处理详解

    1. Java 中的异常 前言:Java 中的异常处理是处理程序运行错误时的强大机制之一,它可以保证应用程序的正常流程. 首先我们将了解java异常.异常的类型以及受查和非受查异常之间的区别. 1.1 ...

  9. Java基础知识:Java实现Map集合二级联动2

    2. 定义获取省份的方法,创建一个Map集合,将上一步得到的映射集合赋值给它,使用Map集合的keySet()方法获取该集合中的所有键对象组成的Set 集合,即为省分集合,创建一个Object型一维数 ...

  10. 《Java基础知识》Java IO流详解

    Java IO概念 1. 用于设备之间的数据传输. 2. Java 将操作数据流的功能封装到了IO包中. 3. 数据流流向分:输入流和输出流,操作对象为文件. 4. 流按照操作数据分:字节流(通用)和 ...

随机推荐

  1. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  2. 解决ASP.NET上传文件大小限制

    第一种方法,主要适用于IIS6.0版本 一.修改配置Web.Config文件中的httpRuntime节点对于asp.net,默认只允许上传4M文件,增加如下配置,一般可以自定义最大文件大小.一.修改 ...

  3. Linux 管道的实现模型

    //管道的实现 //当前目录下实现命令"ls | wc -w" #include <stdio.h> #include <stdlib.h> #includ ...

  4. C#调用天气查询服务

    先引入天气查询服务 1.有点引用导入服务引用 //实例化            web引用名.WeatherWebService cn = new web引用名.WeatherWebService() ...

  5. [LeetCode] Minimum Unique Word Abbreviation 最短的独一无二的单词缩写

    A string such as "word" contains the following abbreviations: ["word", "1or ...

  6. 通过一个实例重新认识引用类型,值类型,数组,堆栈,ref

    昨天在写代码时候遇到了一个问题,百思不得其解,感觉颠覆了自己对C#基础知识的认知,因为具体的情境涉及公司代码不便放出,我在这里举个例子,先上整个测试所有的代码,然后一一讲解我的思考过程: using ...

  7. Android Studio配置OpenCV(非NDK)

    参考:http://www.cnblogs.com/tail/p/4618476.html 工具: 1,Android Studio(AS)1.4 2,Opencv 2.4.11 步骤: 1,解压下载 ...

  8. cx_Oracle摘记

    由于想使用python操作oracle所以查看了cx_Oracle的官方文档,同时也查看了twisted中cx_Oracle的使用.下面是摘自文档中一些我认为有用的内容 cx_Oracle is a ...

  9. BZOJ 1711: [Usaco2007 Open]Dining吃饭

    1711: [Usaco2007 Open]Dining吃饭 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 902  Solved: 476[Submit ...

  10. TypeScript 素描-变量声明

    博文读自 TypeScript 官方文档而来,不具有学习性,仅是本人学习时记录以供日后翻阅 ,有学习TypeScript的朋友还请去看更为详细的官方文档 /* 变量声明在之前的js中一直是使用var关 ...