反射——类(Class)
本文原创,转载请注明原处!
红色代表的是基本组件:包(Package),修饰符(modifier),类(Class),字段(Field),构造器(Constructor)和方法(Method)。
黄色代表的是泛型组件:可定义泛型的元素(GenericDeclaration),类型(Type),泛型(TypeVariable),泛型参数类(ParameterizedType),泛型数组(GenericArrayType),通配符(WildcardType)。
蓝色代表的是注解组件:可被注解的元素(AnnotatedElement),注解后的类型(AnnotatedType),注解(Annotation),其它。
类(Class)
类不是单纯的指class定义的类,它是包括基本数据类型和数组,还包括class,interface,@interface,enum等定义出来的类型。
平常所用到的,所定义出来的类型,都可以归为现在所讲述的这个“类”,但它不包括泛型,虽然说泛型可以作为一个类型来使用。
接口:Type,GenericDeclaration,AnnotatedElement
名称
- getName():String
- getCanonicalName():String
- getSimpleName():String
- s+forName(String):Class<?>
- s+forName(String, boolean, ClassLoader):Class<?>
示例:
public class Test {
public static void main(String[] params) throws ClassNotFoundException {
Class<?> clazz = Class.forName("test.TestClass$TestInnerClass");
System.out.println(clazz.getName());
System.out.println(clazz.getCanonicalName());
System.out.println(clazz.getSimpleName()); /*
运行结果:
test.TestClass$TestInnerClass
test.TestClass.TestInnerClass
TestInnerClass
*/
}
}
test/TestClass.java
public class TestClass {
public class TestInnerClass { }
}
类型
- isPrimitive():boolean
查看是否基本数据类型。 - isArray():boolean
查看是否数组类型。 - isInterface():boolean
查看是否接口类型。 - isAnnotation():boolean
查看是否注解类型。 - isEnum():boolean
查看是否枚举类型。
public class Test {
public static void main(String[] params) {
print("基本数据类型", int.class);
/*
输出结果:
基本数据类型 -> 是否基本数据类型=true
基本数据类型 -> 是否数组= false
基本数据类型 -> 是否接口= false
基本数据类型 -> 是否注解= false
基本数据类型 -> 是否枚举= false
*/ System.out.println("-------------------------");
print("数组", int[].class);
/*
输出结果:
数组 -> 是否基本数据类型=false
数组 -> 是否数组= true
数组 -> 是否接口= false
数组 -> 是否注解= false
数组 -> 是否枚举= false
*/ System.out.println("-------------------------");
print("接口", TestInterface.class);
/*
输出结果:
接口 -> 是否基本数据类型=false
接口 -> 是否数组= false
接口 -> 是否接口= true
接口 -> 是否注解= false
接口 -> 是否枚举= false
*/ System.out.println("-------------------------");
print("注解", TestAnnotation.class);
/*
输出结果:
注解 -> 是否基本数据类型=false
注解 -> 是否数组= false
注解 -> 是否接口= true
注解 -> 是否注解= true
注解 -> 是否枚举= false
*/ System.out.println("-------------------------");
print("枚举", TestEnum.class);
/*
输出结果:
枚举 -> 是否基本数据类型=false
枚举 -> 是否数组= false
枚举 -> 是否接口= false
枚举 -> 是否注解= false
枚举 -> 是否枚举= true
*/ System.out.println("-------------------------");
print("类", TestClass.class);
/*
输出结果:
类 -> 是否基本数据类型=false
类 -> 是否数组= false
类 -> 是否接口= false
类 -> 是否注解= false
类 -> 是否枚举= false
*/
} public static void print(String name, Class<?> clazz){
System.out.println(name + " -> 是否基本数据类型=" + clazz.isPrimitive());
System.out.println(name + " -> 是否数组=\t" + clazz.isArray());
System.out.println(name + " -> 是否接口=\t" + clazz.isInterface());
System.out.println(name + " -> 是否注解=\t" + clazz.isAnnotation());
System.out.println(name + " -> 是否枚举=\t" + clazz.isEnum());
} public static class TestClass { }
public static interface TestInterface { }
public static @interface TestAnnotation { }
public static enum TestEnum { }
}
注意:注解既是注解类型,又是接口类型,但它不能像接口一样,可以被实现。
- getComponentType():Class<?>
该类为数组类型时,可通过此方法获取其组件类型。
示例:
public class Test {
public static void main(String[] params) {
System.out.println(int[].class.getComponentType());
System.out.println(int[][].class.getComponentType()); /*
输出结果:
int
class [I
*/
}
}
包
- getPackage():Package
获取类在定义时所在的包。
修饰符
- getModifiers():int
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Modifier.toString(TestClass.class.getModifiers())); // 输出结果:
// public static final
} public static final class TestClass { }
}
内部定义
网络上查阅中,其中对内部类的划分有常规内部类,静态内部类,局部内部类,匿名内部类。下面的述语中,成员内部类是指常规内部类与静态内部类。
- getDeclaringClass():Class<?>
获取成员内部类在定义时所在的类。 - getEnclosingClass():Class<?>
获取内部类在定义时所在的类。 - getEnclosingConstructor():Constructor
获取局部或匿名内部类在定义时所在的构造器。 - getEnclosingMethod():Method
获取局部或匿名内部类在定义时所在的方法。 - isMemberClass():boolean
查看是否成员内部类。 - isLocalClass():boolean
查看是否局部内部类。 - isAnonymousClass():boolean
查看是否匿名内部类。
示例:
public class Test {
public static void main(String[] params) {
new Test().test();
} public void test(){
printInnerClass("常规内部类", Test.InnerClass.InnerClass2.class);
/*
输出结果:
常规内部类 -> DeclaringClass= class Test$InnerClass
常规内部类 -> EnclosingClass= class Test$InnerClass
常规内部类 -> EnclosingConstructor=null
常规内部类 -> EnclosingMethod= null
常规内部类 -> 是否成员内部类= true
常规内部类 -> 是否局部内部类= false
常规内部类 -> 是否匿名内部类= false
*/ System.out.println("---------------------------------------------------------------------------------------");
printInnerClass("静态内部类", StaticInnerClass.StaticInnerClass2.class);
/*
输出结果:
静态内部类 -> DeclaringClass= class Test$StaticInnerClass
静态内部类 -> EnclosingClass= class Test$StaticInnerClass
静态内部类 -> EnclosingConstructor=null
静态内部类 -> EnclosingMethod= null
静态内部类 -> 是否成员内部类= true
静态内部类 -> 是否局部内部类= false
静态内部类 -> 是否匿名内部类= false
*/ System.out.println("---------------------------------------------------------------------------------------");
class LocalInnerClass { }
printInnerClass("局部内部类", LocalInnerClass.class);
/*
输出结果:
局部内部类 -> DeclaringClass= null
局部内部类 -> EnclosingClass= class Test
局部内部类 -> EnclosingConstructor=null
局部内部类 -> EnclosingMethod= public void Test.test()
局部内部类 -> 是否成员内部类= false
局部内部类 -> 是否局部内部类= true
局部内部类 -> 是否匿名内部类= false
*/ System.out.println("---------------------------------------------------------------------------------------");
Object obj = new Object(){ };
printInnerClass("匿名内部类", obj.getClass());
/*
输出结果:
匿名内部类 -> DeclaringClass= null
匿名内部类 -> EnclosingClass= class Test
匿名内部类 -> EnclosingConstructor=null
匿名内部类 -> EnclosingMethod= public void Test.test()
匿名内部类 -> 是否成员内部类= false
匿名内部类 -> 是否局部内部类= false
匿名内部类 -> 是否匿名内部类= true
*/
} public static void printInnerClass(String name, Class<?> clazz){
System.out.println(name + " -> DeclaringClass=\t" + clazz.getDeclaringClass());
System.out.println(name + " -> EnclosingClass=\t" + clazz.getEnclosingClass());
System.out.println(name + " -> EnclosingConstructor=" + clazz.getEnclosingConstructor());
System.out.println(name + " -> EnclosingMethod=\t" + clazz.getEnclosingMethod());
System.out.println(name + " -> 是否成员内部类=\t" + clazz.isMemberClass());
System.out.println(name + " -> 是否局部内部类=\t" + clazz.isLocalClass());
System.out.println(name + " -> 是否匿名内部类=\t" + clazz.isAnonymousClass());
} public class InnerClass {
public class InnerClass2 { }
} public static class StaticInnerClass {
public static class StaticInnerClass2 { }
}
}
父子关系
- getSuperclass():Class<? super T>
获取继承的父类。 - getGenericSuperclass():Type
- getAnnotatedSuperclass():AnnotatedType
示例:
public class Test {
public static void main(String[] params) {
System.out.println(TestClass.class.getSuperclass());
System.out.println(TestClass.class.getGenericSuperclass());
System.out.println(TestClass.class.getAnnotatedSuperclass());
/*
运行结果:
class Test$TestSuperClass
Test.Test$TestSuperClass<java.lang.Integer>
sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@a14482
*/
} public class TestSuperClass<T> { } public class TestClass extends @TestAnnotation TestSuperClass<Integer>{ } @Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation { }
}
- getInterfaces():Class<?>[]
获取实现的接口集。 - getGenericInterfaces():Type[]
- getAnnotatedInterfaces():AnnotatedType[]
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getInterfaces()));
System.out.println(Arrays.toString(TestClass.class.getGenericInterfaces()));
System.out.println(Arrays.toString(TestClass.class.getAnnotatedInterfaces()));
/*
运行结果:
[interface Test$TestInterface]
[Test.Test$TestInterface<java.lang.Integer>]
[sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@a14482]
*/
} public interface TestSuperInterface { } public interface TestInterface<T> extends TestSuperInterface { } public class TestClass implements @TestAnnotation TestInterface<Integer>{ } @Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation { }
}
- asSubclass(Class<U>):Class<? extends U>
把该类型(子类)转换为目标类型(父类)。 - isAssignableFrom(Class<?>):boolean
测试该类型(父类)是否为目标类型(子类)的父类。
用例:
public class Test {
public static void main(String[] params) {
test(Object.class);
System.out.println("---------------------------------");
test(TestClass.class); /*
输出结果:
test方法 -> 获得一个clazz,但不确定它是否为TestSuperClass类型或其子类
test方法 -> 这个clazz不是TestSuperClass类型或其子类
---------------------------------
test方法 -> 获得一个clazz,但不确定它是否为TestSuperClass类型或其子类
test方法 -> 确认这个clazz是TestSuperClass类型或其子类
*/
} public static Class<? extends TestSuperClass> test(Class<?> clazz){
System.out.println("test -> 获得一个clazz,但不确定它是否为TestSuperClass类型或其子类");
if(TestSuperClass.class.isAssignableFrom(clazz)){
System.out.println("test -> 确认这个clazz是TestSuperClass类型或其子类");
return clazz.asSubclass(TestSuperClass.class);
}
System.out.println("test -> 这个clazz不是TestSuperClass类型或其子类");
return null;
} public class TestSuperClass { } public class TestClass extends TestSuperClass { }
}
成员类
- getClasses():Class<?>[]
- getDeclaredClasses():Class<?>[]
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getClasses()));
System.out.println("---------------------------------");
System.out.println(Arrays.toString(TestClass.class.getDeclaredClasses())); /*
输出结果:
[class Test$TestClass$TestMemberClass3, class Test$TestSuperClass$TestSuperMemberClass3]
---------------------------------
[class Test$TestClass$TestMemberClass1, class Test$TestClass$TestMemberClass2, class Test$TestClass$TestMemberClass3]
*/
} public class TestSuperClass { private class TestSuperMemberClass1 { } protected class TestSuperMemberClass2 { } public class TestSuperMemberClass3 { }
} public class TestClass extends TestSuperClass { private class TestMemberClass1 { } protected class TestMemberClass2 { } public class TestMemberClass3 { } }
}
构造器
- getConstructor(Class<?>...):Constructor<T>
- getConstructors():Constructor<?>[]
- getDeclaredConstructor(Class<?>...):Constructor<T>
- getDeclaredConstructors():Constructor<?>[]
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getConstructors()));
System.out.println(Arrays.toString(TestClass.class.getDeclaredConstructors())); /*
运行结果:
[public Test$TestClass(Test,long)]
[private Test$TestClass(Test,short), protected Test$TestClass(Test,int), public Test$TestClass(Test,long)]
*/
} public class TestClass {
private TestClass(short i){ } protected TestClass(int i){ } public TestClass(long l){ }
}
}
方法
- getMethod(String, Class<?>...):Method
- getMethods():Method[]
- getDeclaredMethod(String, Class<?>...):Method
- getDeclaredMethods():Method[]
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getMethods()));
System.out.println("----------------------------------");
System.out.println(Arrays.toString(TestClass.class.getDeclaredMethods())); /*
运行结果:
[public void Test$TestClass.test(long), public void Test$TestSuperClass.superTest(long), 省略Object的方法……]
----------------------------------
[public void Test$TestClass.test(long), protected void Test$TestClass.test(int), private void Test$TestClass.test(short)]
*/
} public class TestSuperClass {
private void superTest(short i){ } protected void superTest(int i){ } public void superTest(long l){ }
} public class TestClass extends TestSuperClass {
private void test(short i){ } protected void test(int i){ } public void test(long l){ }
}
}
字段
- getField(String):Field
- getFields():Field[]
- getDeclaredField(String):Field
- getDeclaredFields():Field[]
与方法同理……
实例
- newInstance():T
使用该类的无参构造器创建实例。 - isInstance(Object):boolean
测试该对象实例是否为该类的实例。 - cast(Object):T
把对象实例转为该类的实例。 - getEnumConstants():T[]
该类为枚举类型时,可通过此方法获取其所有枚举常量。
资源
- getResource(String):URL
获取与该类所在目录下的路径资源。 - getResourceAsStream(String):InputStream
和上同理……
其它
- desiredAssertionStatus():boolean
测试该类的断言功能是否已打开。
示例:
test/Test.java
public class Test {
public static void main(String[] params) {
Test.class.getClassLoader().setClassAssertionStatus(TestAssert.class.getName(), true);
TestAssert testAssert2 = new TestAssert();
testAssert2.test(); /*
运行结果:
TestAssert -> 断言是否已打开=true
Exception in thread "main" java.lang.AssertionError: 断言信息!
at test.TestAssert.test(TestAssert.java:6)
at test.Test.main(Test.java:10)
*/
}
}
test/TestAssert.java
public class TestAssert {
public void test(){
System.out.println("TestAssert -> 断言是否已打开=" + TestAssert.class.desiredAssertionStatus());
assert false : "断言信息!";
}
}
注:打开断言功能,还可以使用“-ea”参数打开。
- isSynthetic():boolean
测试该类是否由编译器编译成class文件时所增加的,否则它是由编程人员编写java源文件时所编写的。 - getClassLoader():ClassLoader
获取该类被加载时所用的类加载器。 - getProtectionDomain():ProtectionDomain
一种权限机制,制定一个代码源所拥有的权限集合,保护域就是代表一个代码源的权限集合。 - getSigners():Object[]
一种盖章机制,编写者编写完代码后,由签名者审核确认无误后,进行签名,同一代码可以由多个签名者审核后盖章。
反射——类(Class)的更多相关文章
- C# 通过反射类动态调用DLL方法
网上看了很多关于反射的思路和方法,发现这个还算不错 //使用反射方: using System; using System.Collections.Generic; using System.Linq ...
- PHP的反射类ReflectionClass、ReflectionMethod使用实例
PHP5 具有完整的反射API,添加对类.接口.函数.方法和扩展进行反向工程的能力. 反射是什么? 它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类.方法.属性.参数等的详细信息,包括 ...
- 反射类属性生成DataTable
public class People //类名 { private static string name; //字段 private string sex;//字段 public string Se ...
- C#语法糖之 ReflectionSugar 通用反射类
用法很简单: ReflectionSugar rs = new ReflectionSugar(100);//缓存100秒 ,可以不填默认不缓存 rs.有嘛点嘛 性能测试: 性能测试类源码: ht ...
- Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)
反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强 ...
- 01_反射_04_反射类的main方法
[User.java] package com.Higgin.reflect; public class User { public User(){ System.out.println(" ...
- (转载)php反射类 ReflectionClass
(转载)http://hi.baidu.com/daihui98/item/a67dfb8213055dd75f0ec165 php反射类 ReflectionClass 什么是php反射类,可以 ...
- php反射类 ReflectionClass
什么是php反射类,顾名思义,能够理解为一个类的映射.举个样例: class fuc { //定义一个类static function ec() {echo '我是一个类';}}$cla ...
- PHP 反射类学习记录
原文:http://www.upwqy.com/details/58.html 1 开发环境 windows TP5 参考文档 http://php.net/manual/zh/class.refle ...
- 【译】12. Java反射——类的动态加载和重新加载
原文地址:http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html 博主最近比较忙,争取每周翻译 ...
随机推荐
- ruby环境sass编译中文出现Syntax error: Invalid GBK character错误解决方法
sass文件编译时候使用ruby环境,无论是界面化的koala工具还是命令行模式的都无法通过,真是令人烦恼. 容易出现中文注释时候无法编译通过,或者出现乱码,找了几天的解决方法终于解决了. 这个问题的 ...
- gulp和webpack初探
gulp 真正“流程”化工具 我记得实习刚刚进公司看到grunt,还是有点蒙,之前一直是本地开发,游览器F5,没想到前端也需要“编译工具”.所以grunt一直给我的感觉是“编译工具”,你写的很多代码还 ...
- hadoop1中hdfs原理详解
HDFS是Hadoop Distribute File System的简称,也是Hadoop的一个分布四文件系统 一.HDFS的主要设计理念 1.存储超大文件 这里的 “超大文件” 是指几百MB .G ...
- 传感器 -UIAccelerometer
// ios 4 之前 UIAccelerometer // ios 5 <CoreMotion/CoreMotion.h> #import "ViewController.h& ...
- SQL Join PK ChinaJoy
P PK
- 【转载】ASP.NET获取路径的方法
HttpContext.Current.Request.PhysicalPath; // 获得当前页面的完整物理路径.比如 F:\XFU.NSQS\project\website\Default ...
- python之---类和实例
类和实例: 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但 ...
- BZOJ 1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路
Description 农夫约翰正驾驶一条小艇在牛勒比海上航行. 海上有N(1≤N≤100)个岛屿,用1到N编号.约翰从1号小岛出发,最后到达N号小岛.一 张藏宝图上说,如果他的路程上经过的小岛依次出 ...
- [原博客] BZOJ 2242 [SDOI2011] 计算器
题目链接 noip级数论模版题了吧.让求三个东西: 给定y,z,p,计算`Y^Z Mod P` 的值. 给定y,z,p,计算满足`xy≡ Z ( mod P )`的最小非负整数. 给定y,z,p,计算 ...
- cf 219D
树形dp; 思想: 把正向边赋值为0:反向边赋值为1:然后求出点到其他点的最小距离: 两次dfs: 第一次是从下往上:记录每个点到所有子树中需要改变的边的条数: 第二次是自上往下:由父节点求子节点到所 ...