java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式:
java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型)。
对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象。
它提供了在运行时检查对象属性的方法,这些属性包括它的成员和类型信息。
更重要的是Class对象是所有反射API的入口。
Class类是泛型类,可以使用@SuppressWarnings("unchecked")忽略泛型或者使用Class<V>类型。
获得Class对象的5种方式:
1."Object.getClass()" : 如果一个类的对象可用,则最简单的获得Class的方法是使用Object.getClass()。
当然,此方式只对引用类型有效。2. ".class"------------- : 如果类型可用但没有对象,则可以在类型后加上".class"来获得Class对象。这也是使原始类型
获得Class对象最简单的方式:
3."Class.forName()"---: 如果知道类的全名,则可以使用静态方法Class.forName()来获得Class对象,它不能用在原始类型上,但是可以用在原始类型数组上。(注:此方式会抛出ClassNotFoundException异常)
4. "包装类的TYPE域"-----: 每一个原始类型和void都有包装类。利用其TYPE域就可以获得Class对象。5."以Class为返回值的方法": 如获取内部类的getDeclaredClasses()方法,此时返回一个对象数组
--支持知识共享,转载请标注地址"http://www.cnblogs.com/XHJT/p/3915221.html "——和佑博客园,谢谢~~--
代码实例:
package com.xhj.reflection_excetion; /**
* 反射之实例化Class类的5种方式
*
* @author XIEHEJUN
*
*/
public class InstantiateClassObject { @SuppressWarnings("rawtypes")
public static void main(String[] args) throws ClassNotFoundException {
System.out.print("第一种方式--用Object.getClass()方法获取到的String类的对象为: ");
Class class1 = new String().getClass();
System.out.println(class1.getName()); System.out.print("第二种方式--用.class()方法获取到的String类的对象为: ");
class1 = String.class;
System.out.println(class1.getName()); System.out.print("第三种方式--用.forName()方法获取到的String类的对象为: ");
class1 = Class.forName("java.lang.String");
System.out.println(class1.getName()); System.out.print("第四种方式--用包装类的TYPE域获取到的Integer类的对象为: ");
class1 = Integer.TYPE;
System.out.println(class1.getName()); System.out.println("第五种方式--用getDeclaredClasses()获取String类的内部类对象:");
Class<?>[] clazz = new String().getClass().getDeclaredClasses();
for (Class<?> class2 : clazz) {
System.out.println("\t"+class2);
} } }
结果为:
注:除了java.lang.reflect.ReflectPermission和java.lang.reflect包外,所有类都没有公共的
构造方法。为了获得这些类的对象,必须使用Class类中适当的方法,对于不同的数据类型,Class
对象的获得方式是不同。
二.反射之查看类的定义:
通常类的声明包括常见修饰符(public,protected,private,abstract,static,final,strictfp等)、
类的名称、类的泛型参数、类的继承类(实现的接口)、类的注解等信息。
Class类的实例表示正在运行的Java应用程序中的类和接口:
枚举是一种类,注释是一种接口。
每一个数组属于被映射为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象;
基本数据类型和关键字void也表示为Class对象。
Class没有公共的构造方法。
Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的。
Class类常用方法:
forName(String className)-: 根据给定的名称获得Class对象
getAnnotations()------------: 返回此Class对象上存在的注释
getCanonicalName() --------: 返回Java Language Specification 中所定义的底层类的规范化名称
getGenericInterfaces()------: 返回泛型形式的对象类所实现的接口
getGenericSuperclass() -----: 返回泛型形式的对象类所直接继承的超类
getModifuers() --------------: 返回此类或接口以整数编码的Java语言修饰符
getTypeParameters() -------: 按声明顺序返回TypeVariable对象的一个数组
注:Java语言预定义的注解只有@Deprecated可以在运行时获得。
实例代码:
package com.xhj.reflection_excetion; import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable; /**
* 查看类的定义
*
* @author XIEHEJUN
*
*/
public class CheckClassStatement { public static void main(String[] args) throws ClassNotFoundException {
Class<?> classtest = Class.forName("java.util.ArrayList");
System.out.println("1.根据给定的名称获得Class对象:" + classtest.getName());
Annotation[] annotations = classtest.getAnnotations();
System.out.print("2.获取此对象上的注解为:");
if (annotations.length > 0) {
for (Annotation annotation : annotations) {
System.out.println(annotation + "\t");
}
} else {
System.out.println("空");
} System.out.println("3.获得Java语言规范化名称:" + classtest.getCanonicalName()); System.out.println("4.获取类上的修饰符:共有" + classtest.getModifiers()
+ "个,为: " + Modifier.toString(classtest.getModifiers())); TypeVariable<?>[] typeV = classtest.getTypeParameters();
System.out.print("5.在对象上获取到的泛型是:");
if (typeV.length > 0) {
for (TypeVariable<?> typeVariable : typeV) {
System.out.println(typeVariable);
}
} else {
System.out.println("空");
} System.out.println("6.在对象上获取到的接口为:");
// 使用getInterfaces()不包含泛型;使用getGenericInterfaces包含泛型
Type[] intefaces = classtest.getGenericInterfaces();
if (intefaces.length > 0) {
for (Type type : intefaces) {
System.out.println("\t" + type);
}
} else {
System.out.println("空");
}
Class class2 = classtest.getSuperclass();
System.out.print("7.在对象上获取直接继承类:");
if (class2 != null) {
System.out.println(class2);
} else {
System.out.println("空");
} }
}
结果为:
注:getSuperclass()方法也不能获得有泛型信息的父类
三.反射之获得Class对象表示实体的名称
对于不同类型的对象,其Class对象的名称是不同的,反过来说就是从这个名称就可以知道该对象的类型。
注:
1.如果此类对象表示的是非数组类型的引用类型,则返回该类的二进制名称。
2.如果此类对象表示一个基本类型或者void,则返回其对应的Java语言的关键字的字符串。
3.如果此类对象表示一个数组类,名字的内部形式为"[元素编码",其深度为几维,就有几个"["。
其元素类型编码为:
——————————————————————————————————————————————————
元素类型 编 码
boolean Zbyte B
char C
short S
int I
float F
double D
long J
class or interfaces Lclassname(即当元素是引用类型或者接口的时候,编码为"L+类名")
____________________________________________________
实例代码:
package com.xhj.reflection_excetion; /**
* 获取对象实体的名称
*
* @author XIEHEJUN
*
*/
public class GetClassEntityName {
/**
* 数组元素类型编码为:
* 元素类型 编码
* boolean Z
* byte B
* char C
* short S
* int I
* float F
* double D
* long J
* class or interfaces Lclassname(即当元素是引用类型或者接口的时候,编码为"L+类名")
*/
public static void main(String[] args) {
System.out.println("获取非数组类型的引用类型,返回该类的二进制名称: "
+ new String().getClass().getName());
System.out.println("获取基本类型,返回其对应的Java语言的关键字的字符串: "
+ int.class.getName());
System.out.println("获取void类型,返回其对应的Java语言的关键字的字符串: "
+ void.class.getName());
System.out.println("获取一维数组类型的基本类型,返回'[+元素编码': "
+ new int[2].getClass().getName());
System.out.println("获取一维数组类型的引用类型,返回'[+元素编码': "
+ new String[2].getClass().getName());
System.out.println("获取二维数组类型的基本类型,返回'[+元素编码': "
+ new int[2][3].getClass().getName());
System.out.println("获取二维数组类型的引用类型,返回'[+元素编码': "
+ new String[2][3].getClass().getName());
System.out.println("用getCanonicalName()获取二维数组类型的基本类型,返回数组名称"
+ new int[2][3].getClass().getCanonicalName());
System.out.println("用getCanonicalName()获取二维数组类型的引用类型,返回数组名称"
+ new String[2][3].getClass().getCanonicalName());
} }
结果为:
注:
对于数组来说,用getCanonicalName()方法可以获取的到数组的名称,且比较容易接受和辨认
四.反射之查看类的成员
我们要查看类的定义,首先想到的当然是API文档,但若是找不到API文档又该如何呢?此时就要用到Java的反射机制了。
另外我们在无法查看源代码的情况下,也可以通过反射机制查看类的成员,包括"域,构造方法,普通方法和内部类"等。
主要用到的方法:
getConstructors() -------: 返回由该类对象的所有构造方法组成的数组getDeclaredFields() -----: 返回由该类对象的所有非继承域组成的数组
getDeclaredMethods() -- : 返回由该类对象的所有非继承方法组成的数组
getFields() -------------- : 返回由该类对象的所有公共域组成的数组
getMethod() -------------: 返回由该类对象的所有公共方法组成的数组
代码实例:
package com.xhj.reflection_excetion; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* 查看类的成员
*
* @author XIEHEJUN
*
*/
public class CheckClassMembers { public static void main(String[] args) {
Class<?> strclass = new String().getClass(); // 查看构造方法
System.out.println(strclass.getName() + "的构造方法有:");
Constructor<?>[] constructors = strclass.getConstructors();
if (constructors.length > 0) {
for (Constructor<?> constructor : constructors) {
System.out.println("\t" + constructor);
}
} else {
System.out.println("空");
}
// 查看非继承域
System.out.println(strclass.getName() + "的非继承域有:");
Field[] declaredFields = strclass.getDeclaredFields();
if (declaredFields.length > 0) {
for (Field field : declaredFields) {
System.out.println("\t" + field);
}
} else {
System.out.println("空");
} // 查看非继承方法
System.out.println(strclass.getName() + "的非继承方法有:");
Method[] declaredMethods = strclass.getDeclaredMethods();
if (declaredMethods.length > 0) {
for (Method method : declaredMethods) {
System.out.println("\t" + method);
}
} else {
System.out.println("空");
} // 查看所有公共域
System.out.println(strclass.getName() + "的所有域有:");
Field[] fields = strclass.getFields();
if (fields.length > 0) {
for (Field field : fields) {
System.out.println("\t" + field);
}
} else {
System.out.println("空");
} // 查看所有公共的方法
System.out.println(strclass.getName() + "的所有继承方法有:");
Method[] methods = strclass.getMethods();
if (methods.length > 0) {
for (Method method : methods) {
System.out.println("\t" + method);
}
} else {
System.out.println("空");
}
} }
结果为:
(打印出来的数据太多,这里之展示部分结果~)
注:对于私有域或方法,如果有安全管理器,可能会报异常。
五:反射之查看内部类消息
Class类的getDeclaredClasses()方法返回Class对象的一个数组,这些对象反映声明为该Class对象
所表示的类的成员的所有类和接口,包括该类所声明的公共、保护、默认(包)访问及私有类和接口,
但不包括继承的类和接口。若该类不将任何类或接口声明为成员,或者该对象表示基本类型、数组类或
void,则该方法返回一个长度为0的数组。
public Class<?> [] getDeclaredClasses() throws SecurityException
注:利用Class类的getDeclaredClasses()方法可以获得一个数组,其中的每一个成员代表一个内部类的类对象。
然后我们可以像获取普通类的信息一样,获取到内部类的信息。
代码实例:
package com.xhj.reflection_excetion; import java.lang.reflect.Field;
import java.lang.reflect.Method; /**
* 查看内部类的消息
*
* @author XIEHEJUN
*
*/
public class CheckInnerClass { public static void main(String[] args) {
Class<?> clazz = new String().getClass();
Class[] class1 = clazz.getDeclaredClasses();
for (int i = 0; i < class1.length; i++) {
Class<?> innerclass = class1[i];
System.out
.println("================================================================");
System.out.println("内部类" + i + "为: " + innerclass.getName()); System.out.println("内部类" + i + "的父类为:"
+ innerclass.getSuperclass().getName()); System.out.print("内部类" + i + "的所有公共域为:");
Field[] field = innerclass.getFields();
if (field.length > 0) {
System.out.println();
for (Field field2 : field) {
System.out.println("\t" + field2);
}
} else {
System.out.println("空");
} System.out.print("内部类" + i + "的非继承域为:");
Field[] declaredfield = innerclass.getDeclaredFields();
if (declaredfield.length > 0) {
System.out.println();
for (Field field2 : declaredfield) {
System.out.println("\t" + field2);
}
} else {
System.out.println("空");
} System.out.print("内部类" + i + "的所有公共方法为:");
Method[] methods = innerclass.getMethods();
if (methods.length > 0) {
System.out.println();
for (Method method : methods) {
System.out.println("\t" + method);
}
} else {
System.out.println("空");
} System.out.print("内部类" + i + "的非继承方法为:");
Method[] declaredmethods = innerclass.getDeclaredMethods();
if (declaredmethods.length > 0) {
System.out.println();
for (Method method : declaredmethods) {
System.out.println("\t" + method);
}
} else {
System.out.println("空");
} } } }
结果为:
(打印出来的数据太多,这里之展示部分结果~)
六.反射之按继承层次对类排序
Java提供了instanceof运算符来比较两个类(或接口)之间是否存在继承关系。
但是对于多个类来说,这种方法是很麻烦的。这时候,我们要做的应该是利用
java的反射机制来对存在继承关系的类进行排序。
主要方法:
TreeSet<E> 是基于TreeMap的NavigableSet实现的。它使用元素的自然顺序对
元素进行排序,或者根据创建set时提供的Comparator进行排序,具体取决于
使用的构造方法。本节采用Class类中的isAssignableFrom()方法来判断当前
Class 对象所表示的类与给定的Class对象所表示的类之间的关系,若相同或
是父类则返回true,否则返回false。
public boolean isAssignableFrom(Class<?> clazz)
注:Java中与排序相关的接口有Comparable和Comparator。这两个接口通过对象之间比较的结果--一个有符号的整数来比较对象的大小。实现任何一个接口都可
以让对象具有排序的能力。固可以用TreeSet也可以用Arrays.sort()来进行排序。
代码实例:
package com.xhj.reflection_excetion; import java.awt.Container;
import java.util.Comparator;
import java.util.TreeSet; import javax.swing.JComponent;
import javax.swing.JPanel; /**
* 比较并将类按继承关系排序
*
* @author XIEHEJUN
*
*/
public class CompareClasses implements Comparator<Class<?>> { @Override
public int compare(Class<?> o1, Class<?> o2) {
if (o1.equals(o2)) {
return 0;
} else if (o1.isAssignableFrom(o2)) {
return -1;
} else if (o2.isAssignableFrom(o1)) {
return 1;
} else {
throw new IllegalArgumentException(o1+"和"+o2+"两个类之间没有联系");
}
} public static void main(String[] args) {
TreeSet<Class<?>> treeSet = new TreeSet<Class<?>>(
new CompareClasses());
System.out.println("添加类——JComponent.class");
treeSet.add(JComponent.class);
System.out
.println("添加类——Container.class");
treeSet.add(Container.class);
System.out.println("添加类——JPanel.class");
treeSet.add(JPanel.class);
System.out.println("=================排序后为=====================");
for (Class<?> class1 : treeSet) {
System.out.println(class1);
}
} }
结果为:
java笔记--反射机制之基础总结与详解的更多相关文章
- Java笔记--反射机制
1.Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法. 2.Java反射机制提供 ...
- JAVA的反射机制学习笔记(二)
上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了.自己的步伐全然被打乱了~不能继续被动下去.得又一次找到自己的节奏. 4.获取类的Constructor 通过反射机制得到 ...
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- Java的反射机制Reflect
简介: 动态获取类的信息.动态调用对象的方法的功能叫做:Java 的反射(Reflection)机制. Reflection是不同于C++等静态语言,而被视为准动态语言的关键性质.反射机制允许程序在运 ...
- java的反射机制浅谈(转)
原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...
- 深入浅出学习hibernate框架(三):java的反射机制
上篇博客写到了JDBC的基本操作,今天准备写一篇关于JAVA反射机制的文章,因为java的反射机制和上一篇JDBC都是Hibernate框架的基本要素.在Hibernate的运行机制中,这两块的内容正 ...
- java利器------反射机制
java反射的概念:java的反射机制是指在运行状态下,对于一个类来说,可以得到这个类的所有方法和属性.对于一个对象来说,可以调用这个对象的人和方法和属性. 反射机制首先会拿到该类的字节码文件(Cla ...
- 【设计模式】Java设计模式 - 反射机制
[设计模式]Java设计模式 - 反射机制 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 目录 [设计模式]Java设计模式 - 反射 ...
随机推荐
- Java并发编程-ReentrantLock
代码示例: Lock lock = new ReentrantLock(); lock.lock(); try { // update object state } finally { lock.un ...
- Bootstrap系列 -- 37. 基础导航样式
Bootstrap框架中制作导航条主要通过“.nav”样式.默认的“.nav”样式不提供默认的导航样式,必须附加另外一个样式才会有效,比如“nav-tabs”.“nav-pills”之类.比如右侧代码 ...
- opc 方面研究
http://opcuaservicesforwpf.codeplex.com/ WPF + OPC UA
- 利用 NSSortDescriptor 对 NSMutableArray 排序
有时我们在NSMutableArray中存的是网络请求返回的数据,而每一个元素又是一个NSDictionary,如果这时候需要把数组中的元素按照每个元素字典中某一个key来排序,那么我们可以利用Obj ...
- 笔记:js的replace函数
replace函数 js的replace函数与c#的有一个不同,js的只替换第一个字符 例如,var a=',1,2' var b=a.replace(',','') 结果b='1,2'(ps:这是一 ...
- MVC4 code first 增加属性,对应自动修改列的方法笔记
VS工具>库程序包管理器>程序包管理控制台,然后输入以下命令 enable-migrations -contexttypename Mvc4Application1.Models.Movi ...
- 传智168期JavaEE就业班 day03-js
* 课程回顾: * CSS * CSS的简介 * 层叠样式表. * CSS与HTML的结合(4种) * HTML的标签提供了属性 style="CSS的代码" * HTML提供了标 ...
- 【转】div居中代码 DIV水平居中显示CSS代码
原文地址:http://www.divcss5.com/rumen/r622.shtml 如何使用CSS让DIV居中显示,让div水平居中有哪些CSS样式呢? 需要的主要css代码有两个,一个为tex ...
- Productivity Power Tools 动画演示--给力的插件工具
免费的精品: Productivity Power Tools 动画演示 Productivity Power Tools 是微软官方推出的 Visual Studio 扩展,被用以提高开发人员生产率 ...
- ZOJ 3201 树形dp+背包(简单题)
#include<cstdio> #include<vector> #include<cstring> #include<iostream> using ...