ClassesJava中,任何一个对象要么是一个引用类型要么是基本数据类型.引用类型指的是那些直接或间接

Java.lang.Object的类.Classse,enum,和接口都是应用类型.基本类型是一个固定的集合,它包括:

boolean, byte,short, int, long,char,float, double. java.lang.String和所有的基本类型的

包裹类(Wrapper classes),比如java.lang.Double,接口java.io.Serializabl,和枚举

Jvax.swing.SortOrder都是引用类型.

对于每种类型的对象,java虚拟机都会为其初始化一个不变的java.lang.Class实例.这个实例提供了可以在运

行时检查对象属性的方法.Class对象还具有创建一个新对象的能力.最重要的是,它是所有java发射的入口.

1.获取Class对象

Java.lang.reflect包下的所有类都没有公共的构造函数.要得到Class对象,,需要调用Class类中的适当的方法。

有几种法可以得到一个Class对象:

a.使用Object.getClass()

果已经有一个要反射的;类的实例,那么最简单的方法去获得该类的Class对象便是使用Object.getClass()方法.

然而这个方法只适用于要反射的类是引用类型.给出一些示例进行说明:

Class c = "string".getClass();

返回String类的Class对象 enum E { A, B }

Class c = A.getClass();

A是一个枚举类型,因此getClass(),返回枚举类型E的Class对象.

byte[] bytes = new byte[1024];

Class c = bytes.getClass();

因为数组也是Objects,因此可以对数组调用getClass(), 该示例返回的是byte的Class对象.

import java.util.HashSet;

import java.util.Set;

Set s = new HashSet();

Class c = s.getClass();

在这个示例中,java.util.Set是一个接口,而java.util.HashSet实现了这个借口,那么getClass()返回的Class对象是java.util.HashSet的Class对象.

b.使用.class 语法

如果你只知道这个类型,但是却没办法得到这个类型的一个实例,那么获得该类型的Class对象的一种方法便

是使用.class.同时这也是最简单的获得基本类型得Class实例的方法.下面给出一些示例进行说明:

boolean b;

Class c = b.getClass(); // compile-time error

Class c = boolean.class; // correct

语句boolean.getClass()将会产生一个编译时错误,因为Boolean是一个基本数据类型,不能使用该方法获取Class对象.

Class c = java.io.PrintStream.class;

Class c = int[][][].class;

c.Class.forName()

如果你知道一个class文件的完全名称,你可以使用Class类中的静态方法Class.forName()获取类的Class对象.

Class c = Class.forName("com.duke.MyLocaleServiceProvider");

这条语句将会创建一个Class实例使用参数中指定的类.

Class cDoubleArray = Class.forName("[D");

Class cStringArray = Class.forName("[[Ljava.lang.String;");

变量cDoubleArray将包含一个基本类型Double的Class实例,该语句等价于double[].class

变量CStringArray中包含了一个对应于两个维度的String数组的Class对象.该语句等价于String[][].class

d.基本类型包裹类的TYPE属性

.class语法是一个很方便的获得基本类型的class对象的方法,然而还有另外一种方法可以获得基本

类型的Class对象.所有的基本类型和void都有一个包裹类在java.lang包中.这些类将基本类型封装起来

形成了一个引用类型.同时每个包裹类都包含了一个属性叫做TYPE.TYPE等同于基本类型的Class对象.

Class c = Double.TYPE;

Class c = Void.TYPE;

e.返回类型是Class对象的方法有一些反射API方法可以返回Class对象,但是你想要使用这些方法你需要已经直接或者间接的得到了

class对象.给出示例进行说明:

Class.getSuperclass()

返回该类的父类的class对象.

Class c = javax.swing.JButton.class.getSuperclass();

javax.swing.JButton 的父类是 javax.swing.AbstractButton.

Class.getClasses()

返回该类的成员,包括所有公共类,接口,枚举和继承的成员.Class>[] c = Character.class.getClasses();

Character 中包含两个类 Character.Subset,Character.UnicodeBlock.

Class.getDeclaredClasses() 返回所有该类中所有显示声明的接口和枚举

Class>[] c = Character.class.getDeclaredClasses();

Character 包含两个公共类Character.Subset 和 Character.UnicodeBlock 和一个私有的类Character.CharacterCache

Class.getDeclaringClass()

java.lang.reflect.Field.getDeclaringClass()

java.lang.reflect.Method.getDeclaringClass()

java.lang.reflect.Constructor.getDeclaringClass() 返回定义该成员的类的Class实例.

import java.lang.reflect.Field;

Field f = System.class.getField("out");

Class c = f.getDeclaringClass();

2.获取类的修饰符和类型

一个类可以有一个或者多个控制符

访问控制符: publicprotected, and private

需要重写控制符: abstract

限定一个实例控制符:static

禁止修改控制符: final

迫使严格浮点控制符: strictfp

注解

ClassDeclarationSpy 演示了如何获取一个类的声明的组件,包括该类的修饰符,泛型参数,实现的接口,和继承路径.

如果你实现了 java.lang.reflect.AnnotatedElement ,就可以获取运行时注解.

import java.lang.annotation.Annotation;

import java.lang.reflect.Modifier;

import java.lang.reflect.Type;

import java.lang.reflect.TypeVariable;

import java.util.Arrays;

import java.util.ArrayList;

import java.util.List;

import static java.lang.System.out;

public class ClassDeclarationSpy {

public static void main(String... args) {

try {

Class> c = Class.forName(args[0]);

out.format("Class:%n %s%n%n", c.getCanonicalName());

out.format("Modifiers:%n %s%n%n",

Modifier.toString(c.getModifiers()));

out.format("Type Parameters:%n");

TypeVariable[] tv = c.getTypeParameters();

if (tv.length != 0) {

out.format(" ");

for (TypeVariable t : tv)

out.format("%s ", t.getName());

out.format("%n%n");

} else {

out.format(" -- No Type Parameters --%n%n");

}

out.format("Implemented Interfaces:%n");

Type[] intfs = c.getGenericInterfaces();

if (intfs.length != 0) {

for (Type intf : intfs)

out.format(" %s%n", intf.toString());

out.format("%n");

} else {

out.format(" -- No Implemented Interfaces --%n%n");

}

out.format("Inheritance Path:%n");

List l = new ArrayList();

printAncestor(c, l);

if (l.size() != 0) {

for (Class> cl : l)

out.format(" %s%n", cl.getCanonicalName());

out.format("%n");

} else {

out.format(" -- No Super Classes --%n%n");

}

out.format("Annotations:%n");

Annotation[] ann = c.getAnnotations();

if (ann.length != 0) {

for (Annotation a : ann)

out.format(" %s%n", a.toString());

out.format("%n");

} else {

out.format(" -- No Annotations --%n%n");

}

// production code should handle this exception more gracefully

} catch (ClassNotFoundException x) {

x.printStackTrace();

}

}

private static void printAncestor(Class> c, List l) {

Class> ancestor = c.getSuperclass();

if (ancestor != null) {

l.add(ancestor);

printAncestor(ancestor, l);

}

}

}

给出一个运行实例.

$ java ClassDeclarationSpy java.util.concurrent.ConcurrentNavigableMap

Class:

java.util.concurrent.ConcurrentNavigableMap

Modifiers:

public abstract interface

Type Parameters:

K V

Implemented Interfaces:

java.util.concurrent.ConcurrentMap

java.util.NavigableMap

Inheritance Path:

-- No Super Classes --

Annotations:

-- No Annotations -

它被声明在java.util.concurrent.ConcurrentNavigableMap 中,声明如下:

public interface ConcurrentNavigableMap

extends ConcurrentMap, NavigableMap

注意,因为它是一个接口,它隐式的是abstract.编译器会自动的将这个修饰符添加进去.

$ java ClassDeclarationSpy "[Ljava.lang.String;"

Class:

java.lang.String[]

Modifiers:

public abstract final

Type Parameters:

-- No Type Parameters --

Implemented Interfaces:

interface java.lang.Cloneable

interface java.io.Serializable

Inheritance Path:

java.lang.Object

Annotations:

-- No Annotations --

由于数组是运行时的对象,因此它的所有信息被java虚拟机定义.特别的是,数组实现了 Cloneable和java.io.Serializable

和它的直接父类是Object.

$ java ClassDeclarationSpy java.io.InterruptedIOException

Class:

java.io.InterruptedIOException

Modifiers:

public

Type Parameters:

-- No Type Parameters --

Implemented Interfaces:

-- No Implemented Interfaces --

Inheritance Path:

java.io.IOException

java.lang.Exception

java.lang.Throwable

java.lang.Object

Annotations:

-- No Annotations --

$ java ClassDeclarationSpy java.security.Identity

Class:

java.security.Identity

Modifiers:

public abstract

Type Parameters:

-- No Type Parameters --

Implemented Interfaces:

interface java.security.Principal

interface java.io.Serializable

Inheritance Path:

java.lang.Object

Annotations:

@java.lang.Deprecated()

3.访问类成员

在Class中有两类方法可以用来访问类的字段,方法,构造函数.第一类方法是查找本类中特定的方法,

另一类是查找本类及其父类的方法.

在面的表格是对这些方法的简单总结.

Class Methods for Locating Fields

List of members?Inherited members?Private members?Class Methods for Locating Methods

List of members?Inherited members?Private members?Class Methods for Locating Constructors

List of members?Inherited members?Private members?1 Constructors are not inherited..

给出你感兴趣的类的名称和类成员的类型(CONSTRUCTOR, FIELD, METHOD, CLASS, ALL),ClassSpy 将会使用get*s()

方法去得到该类型公共成员的列表,包括继承的成员,

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.lang.reflect.Member;

import static java.lang.System.out;

enum ClassMember { CONSTRUCTOR, FIELD, METHOD, CLASS, ALL }

public class ClassSpy {

public static void main(String... args) {

try {

Class> c = Class.forName(args[0]);

out.format("Class:%n %s%n%n", c.getCanonicalName());

Package p = c.getPackage();

out.format("Package:%n %s%n%n",

(p != null ? p.getName() : "-- No Package --"));

for (int i = 1; i < args.length; i++) {

switch (ClassMember.valueOf(args[i])) {

case CONSTRUCTOR:

printMembers(c.getConstructors(), "Constructor");

break;

case FIELD:

printMembers(c.getFields(), "Fields");

break;

case METHOD:

printMembers(c.getMethods(), "Methods");

break;

case CLASS:

printClasses(c);

break;

case ALL:

printMembers(c.getConstructors(), "Constuctors");

printMembers(c.getFields(), "Fields");

printMembers(c.getMethods(), "Methods");

printClasses(c);

break;

default:

assert false;

}

}

// production code should handle these exceptions more gracefully

} catch (ClassNotFoundException x) {

x.printStackTrace();

}

}

private static void printMembers(Member[] mbrs, String s) {

out.format("%s:%n", s);

for (Member mbr : mbrs) {

if (mbr instanceof Field)

out.format(" %s%n", ((Field)mbr).toGenericString());

else if (mbr instanceof Constructor)

out.format(" %s%n", ((Constructor)mbr).toGenericString());

else if (mbr instanceof Method)

out.format(" %s%n", ((Method)mbr).toGenericString());

}

if (mbrs.length == 0)

out.format(" -- No %s --%n", s);

out.format("%n");

}

private static void printClasses(Class> c) {

out.format("Classes:%n");

Class>[] clss = c.getClasses();

for (Class> cls : clss)

out.format(" %s%n", cls.getCanonicalName());

if (clss.length == 0)

out.format(" -- No member interfaces, classes, or enums --%n");

out.format("%n");

}

}

给出一个示例,以及相应输出结果

$ java ClassSpy java.lang.ClassCastException CONSTRUCTOR

Class:

java.lang.ClassCastException

Package:

java.lang

Constructor:

public java.lang.ClassCastException()

public java.lang.ClassCastException(java.lang.String

给出一个示例,以及相应输出结果

$ java ClassSpy java.nio.channels.ReadableByteChannel METHOD

Class:

java.nio.channels.ReadableByteChannel

Package:

java.nio.channels

Methods:

public abstract int java.nio.channels.ReadableByteChannel.read

(java.nio.ByteBuffer) throws java.io.IOException

public abstract void java.nio.channels.Channel.close() throws

java.io.IOException

public abstract boolean java.nio.channels.Channel.isOpen()

$ java ClassSpy ClassMember FIELD METHOD

Class:

ClassMember

Package:

-- No Package --

Fields:

public static final ClassMember ClassMember.CONSTRUCTOR

public static final ClassMember ClassMember.FIELD

public static final ClassMember ClassMember.METHOD

public static final ClassMember ClassMember.CLASS

public static final ClassMember ClassMember.ALL

Methods:

public static ClassMember ClassMember.valueOf(java.lang.String)

public static ClassMember[] ClassMember.values()

public final int java.lang.Enum.hashCode()

public final int java.lang.Enum.compareTo(E)

public int java.lang.Enum.compareTo(java.lang.Object)

public final java.lang.String java.lang.Enum.name()

public final boolean java.lang.Enum.equals(java.lang.Object)

public java.lang.String java.lang.Enum.toString()

public static T java.lang.Enum.valueOf

(java.lang.Class,java.lang.String)

public final java.lang.Class java.lang.Enum.getDeclaringClass()

public final int java.lang.Enum.ordinal()

public final native java.lang.Class> java.lang.Object.getClass()

public final native void java.lang.Object.wait(long) throws

java.lang.InterruptedException

public final void java.lang.Object.wait(long,int) throws

java.lang.InterruptedException

public final void java.lang.Object.wait() hrows java.lang.InterruptedException

public final native void java.lang.Object.notify()

public final native void java.lang.Object.notifyAll()

接口 java.nio.channels.ReadableByteChannel 定义了 read().

其余的方法都是继承自父类.

对于字段结果的字段部分,枚举常量被列了出来.

对于字段结果的方法部分,发现方法的名称包括定义这个方法的类的名称. toString() 方法是被Enum是实现的,而不是

继承Object的.如果使用Field.getDeclaringClass(),段代码可以被修改的更加明显.下面的代码段展示了一个可行的解决办法:

if (mbr instanceof Field) {

Field f = (Field)mbr;

out.format(" %s%n", f.toGenericString());

out.format(" -- declared in: %s%n", f.getDeclaringClass());

}

java反射基础_Java反射基础(一)--Class对象获取相关推荐

  1. java 反射练习_JAVA反射的基础学习

    反射 :reflection 程序的一种内省机制 程序可以在运行期间动态的创建对象,获取对象类型,调用对象行为 内省机制在java和.net语言中有,在早期的C,C++,delphi,vb这些语言都没 ...

  2. 反射 字段_java核心基础之反射

    前言 大家好,我是 jack xu,今天跟大家介绍核心基础里面的反射,反射这个东西你说它重要也重要,不重要也不重要.重要是当你看一些框架的源码时候,里面会用到反射的代码,你不会是看不懂的.不重要是因为 ...

  3. J2SE基础_JAVA反射基础解析

    很多优秀的开源框架基本原理就是反射,我认为自己不能不重视它 2020.04.18 一.简单了解Java.lang.reflect包 反射机制的相关类 Class类:代表类的实体,在运行的Java应用程 ...

  4. java 反射机制_Java反射机制原理探究

    反射是Java中的一个重要的特性,使用反射可以在运行时动态生成对象.获取对象属性以及调用对象方法.与编译期的静态行为相对,所有的静态型操作都在编译期完成,而反射的所有行为基本都是在运行时进行的,这是一 ...

  5. java反射机制_java反射机制的讲解

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

  6. java反射技术_java反射技术,逆向开发必备技能

    相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了, ...

  7. 哪些类用来实现java反射机制_JAVA反射机制

    运行时类型识别(Run-time Type Identification, RTTI)主要有两种方式,一种是我们在编译时和运行时已经知道了所有的类型,另外一种是功能强大的"反射"机 ...

  8. java反射类型转换_java反射(转)

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道 ...

  9. java 反射代价_Java反射机制

    # 反射 ## 什么是反射 反射是Java提供的动态执行机制, 可以动态加载类, 动态创建对象, 动态访问属性, 动态调用方法.. 静态执行: Java代码经过编译以后就确定的执行次序, 称为静态执行 ...

  10. 零基础java自学就业_java零基础到就业需要多长时间呢?

    展开全部 先以肯定的语气说明一下自学e68a84e8a2ad62616964757a686964616f31333433663030Java,多久可以找到工作: 按照目前Java的体系来说,Java的 ...

最新文章

  1. java编程赋值运算符_跟我学java编程—简单赋值运算符“=”
  2. HuMoments函数
  3. 关于MySQL出现`lock wait timeout exceeded; try restarting transaction` 的解决方案
  4. 编码文件AndroidStudio初体验:解决Execution failed for task ':TestAndroid:compileDebug'.
  5. 这是Blazor上传文件的最佳方式吗?
  6. echarts 地图自定义图标_DMKB08:Echarts 分段设色
  7. 行为设计模式 - 访客设计模式
  8. python ca模块_python学习之模块-模块(五)
  9. jvm调优工具_JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用
  10. 雷电模拟器 脚本_精灵盛典辅助雷电模拟器使用教程
  11. 【运维技术】数据库主从同步搭建
  12. 根据身份证号判断该人的年龄、性别、出生年月日
  13. AD绘制PCB经验总结3-规则报警 Silk primitive without silk layer+Minimum Solder Mask Sliver
  14. 健康低辐射,信号全覆盖,飞鱼星i-Home覆盖方案上市
  15. 文本文件与二进制文件区别 r 与 rb 方式 w 与 wb方式(windows)—————— 开开开山怪
  16. docker安装shipyard
  17. 基于E4A的蓝牙APP
  18. plc服务器作用,工业控制系统以及PLC的简单介绍
  19. 华为 H3C 配置 Portal认证 mac-trigger快速认证 Mac无感知认证 Radius认证计费 对接 外部Portal认证计费系统 案例
  20. vasp算表面吸附流程_VASP表面吸附计算实例分析

热门文章

  1. linux常用指令 查看端口占用情况
  2. C#LeetCode刷题之#202-快乐数(Happy Number)
  3. 经过5年的娱乐功能,编码传奇MPJ踏上了他的下一个大旅程
  4. docker前后端分离_Docker分离模式介绍
  5. magic feature_停止将PostgREST称为“ MAGIC”!
  6. 147_Power BI Report Server demo演示
  7. urllib2:URLError与HTTPError
  8. Django的get和post请求处理
  9. ie678,FF,chrome的css兼容性
  10. Visual Studio 2008下AJAX的设置