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对象。

  下面是一段代码示例:

public class ObtainClass {

    public static void main(String[] args) {
try {
String str1 = "abc";
System.out.println("通过Object的getClass()方法获取 : " + str1.getClass());
System.out.println("使用.class的方式获取 : " + String.class);
System.out.println("使用Class.forName()方法获取 : " + Class.forName("java.lang.String"));
System.out.println(str1.getClass() == String.class);
System.out.println(str1.getClass() == Class.forName("java.lang.String"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} }

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

2、Class类的常用方法

public class ClassTest {
public static void main(String[] args) {
try {
System.out.println("返回与带有给定字符串名的类或接口相关联的 Class 对象 : " + Class.forName("com.classTest.classload.CTest"));
System.out.println("以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称 : " + Class.forName("com.classTest.classload.CTest").getName());
System.out.println("获取此类的包 : " + Class.forName("com.classTest.classload.CTest").getPackage());
System.out.println("使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象 : " + Class.forName("com.classTest.classload.CTest", true, ClassLoader.getSystemClassLoader()));
System.out.println("返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class : " + Class.forName("com.classTest.classload.CTest").getSuperclass());
System.out.println("返回源代码中给出的底层类的简称 : " + Class.forName("com.classTest.classload.CTest").getSimpleName());
System.out.println("获取此类的标记 : " + Class.forName("com.classTest.classload.CTest").getSigners()); CTest ct = new CTest();
System.out.println("如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null : " + ct.annotationType());
System.out.println("返回 Java Language Specification 中所定义的底层类的规范化名称 : " + Class.forName("com.classTest.classload.CTest").getCanonicalName());
System.out.println("返回一个包含某些 Class 对象的数组,这些对象表示属于此 Class 对象所表示的类的成员的所有公共类和接口 : " + Class.forName("com.classTest.classload.CTest").getClasses());
System.out.println("返回该类的类加载器 : " + Class.forName("com.classTest.classload.CTest").getClassLoader());
System.out.println("返回表示数组组件类型的 Class : " + Class.forName("com.classTest.classload.CTest").getComponentType()); System.out.println("返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法 : " + Class.forName("com.classTest.classload.CTest"));
System.out.println("返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法 : " + Class.forName("com.classTest.classload.CTest").getConstructors().length); System.out.println("返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 : " + Class.forName("com.classTest.classload.CTest").getDeclaredField("age").getName());
System.out.println("返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段 : " + Class.forName("com.classTest.classload.CTest").getDeclaredFields().length);
System.out.println("返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 : " + Class.forName("com.classTest.classload.CTest").getField("str"));
System.out.println("返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段 : " + Class.forName("com.classTest.classload.CTest").getFields().length); System.out.println("返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法 : " + Class.forName("com.classTest.classload.CTest").getDeclaredMethod("annotationType").getName());
System.out.println("返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法 : " + Class.forName("com.classTest.classload.CTest").getDeclaredMethods().length);
System.out.println("如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法 : " + Class.forName("com.classTest.classload.CTest").getEnclosingMethod());
System.out.println("返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法 : " + Class.forName("com.classTest.classload.CTest").getMethod("annotationType"));
System.out.println("返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法 : " + Class.forName("com.classTest.classload.CTest").getMethods().length); System.out.println("返回此类或接口以整数编码的 Java 语言修饰符 : " + Class.forName("com.classTest.classload.CTest").getModifiers()); System.out.println("如果此 Class 对象表示一个注释类型则返回 true : " + Class.forName("com.classTest.classload.ETest").isAnnotation());
System.out.println("当且仅当底层类是匿名类时返回 true : " + Class.forName("com.classTest.classload.ETest").isAnonymousClass());
System.out.println("判定此 Class 对象是否表示一个数组类 : " + Class.forName("com.classTest.classload.ETest").isArray());
System.out.println("判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口 : " + Class.forName("com.classTest.classload.ETest").isAssignableFrom(Class.forName("com.classTest.classload.ETest")));
System.out.println("当且仅当该类声明为源代码中的枚举时返回 true : " + Class.forName("com.classTest.classload.ETest").isEnum());
System.out.println("判定指定的 Object 是否与此 Class 所表示的对象赋值兼容 : " + Class.forName("com.classTest.classload.CTest").isInstance(Class.forName("com.classTest.classload.CTest").newInstance()));
System.out.println("判定指定的 Class 对象是否表示一个接口类型 : " + Class.forName("com.classTest.classload.CTest").isInterface());
System.out.println("当且仅当底层类是本地类时返回 true : " + Class.forName("com.classTest.classload.CTest").isLocalClass());
System.out.println("当且仅当底层类是成员类时返回 true : " + Class.forName("com.classTest.classload.CTest").isMemberClass());
System.out.println("判定指定的 Class 对象是否表示一个基本类型 : " + Class.forName("com.classTest.classload.CTest").isPrimitive());
System.out.println("如果此类是复合类,则返回 true,否则 false : " + Class.forName("com.classTest.classload.CTest").isSynthetic());
System.out.println("创建此 Class 对象所表示的类的一个新实例 : " + Class.forName("com.classTest.classload.CTest").newInstance().toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
} class CTest implements Annotation{
private int age;
private String name;
public String str; public Class<? extends Annotation> annotationType() {
return CTest.class;
} @Override
public String toString() {
return "CTest{" +
"age=" + age +
", name='" + name + '\'' +
", str='" + str + '\'' +
'}';
}
} enum ETest{
CN,
EN
}

二、Method类

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

public class MethodTest {

    public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.classTest.classload.MT");
Method[] m = clazz.getMethods();
for (Method mh : m) {
System.out.print(mh.getName() + " | " + mh.getDefaultValue() + " | " + mh.getReturnType());
Class[] c = mh.getParameterTypes();
System.out.print(" | len = " + c.length + " | ");
for (Class tv : c) {
System.out.print(" " + tv.getName());
}
System.out.println();
} Method method = clazz.getMethod("mt", String.class);
method.invoke(clazz.newInstance(), "test method");// 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法
} } class MT {
public String mt(String str) {
System.out.println(str);
return str;
}
}

三、Field类

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

public class FieldTest {

    public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.classTest.classload.FT");
Field[] f = clazz.getFields();
for(Field fd : f) {
System.out.println(fd.getName() + " | " + fd.getType() + " | " + fd.getModifiers() + " | " + fd.get(""));
} } } class FT{
public static String name = "name";
public static int age = 11;
}

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. Checkstyle:整洁你的代码

    内容 Checkstyle简介 下载 Checkstyle的几种使用方式 1) 与Ant结合使用 2) 通过CLI使用 3)在IDE上使用插件 4)在Maven上使用插件 Checkstyle配置 配 ...

  2. [LeetCode] Flatten Binary Tree to Linked List 将二叉树展开成链表

    Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / \ 2 5 / \ \ 3 4 6 T ...

  3. js自定义验证码

    分享一个js自定义的验证码 window.onload = function () {     var code;     $('.changePassword').click(function () ...

  4. 百度广告 高亮 Chrome插件(附源码)

    一前言 百度最近是上了舆论头条了,相信中过百度毒的人对百度都反感.百度自己挖了这么多坑,终究还是要自己来填.国内网民使且最频繁的搜过 还是以百度为主,而百度依靠这种市场占有率靠他的广告竞价排名大发横财 ...

  5. LTE中的各种ID含义

    原文链接:http://www.hropt.com/ask/?q-7128.html ECI (28 Bits) = eNB ID(20 Bits) + Cell ID(8 Bits) 换成16进制就 ...

  6. c++局域网多播

    转自http://www.51cto.com/specbook/17/35216.htm Visual C++实现局域网IP多播 在局域网中,管理员常常需要将某条信息发送给一组用户.如果使用一对一的发 ...

  7. 【转】fatal error C1900: “P1”(第“20081201”版)和“P2”(第“20080116”版)之间 Il 不匹配

    转自:这里(然而这里并没有写原出处) 背景:今天傻逼逼地想用vs2010来编译一个vs2013的项目,其中这个项目用到了一个库(应该是用2013编译的) 在我浅薄的认知中,以为只是13支持的特性更多, ...

  8. java利用JDK调用并执行js源码

    前言: 不同开发语言之间具有通用性,更具有协作调用的可能.有时候对于一些场景会有调用js的需求,因此下面展示了一个java利用自身JDK调用js函数的demo,供感兴趣的朋友参考. js函数文件 ex ...

  9. Leetcode 259. 3Sum Smaller

    class Solution(object): def threeSumSmaller(self, nums, target): """ :type nums: List ...

  10. 爬虫框架--webmagic

    官方有详细的使用文档:http://webmagic.io/docs/zh/ 简介:这只是个java爬虫框架,具体使用需要个人去定制,没有图片验证,不能获取js渲染的网页,但简单易用,可以通过xpat ...