Java反射获取类和对象信息全解析
反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题。
在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了。
获取类对象
- Class.forName(String clazzName)静态方法
- 调用类的class属性,Person.class返回的就是Person的class对象(推荐使用)
- 调用某个对象的getClass()方法
具体使用还是要根据实际来选择,第一种方式是比较自由的,只要知道一个类名就可以了,其不会做该类是否存在的校验,第二种、第三种则会做校验
获取类的信息
获取类构造器
Connstructor<T> getConstructor(Class<?>...parameterTypes)
:返回此Class对象对应类的带指定形参的public构造器Constructor<?>[] getConstructors()
:返回此Class对象对应类的所有public构造器Constructor<T>[] getDeclaredConstructor(Class<?>...parameterTypes)
:返回此class对象对应类的带指定参数的构造器,与构造器的访问权限无关Constructor<?>[] getDeclaredConstructors()
:返回此class对象对应类的所有构造器,与构造器的访问权限无关
获取类成员方法
Method getMethod(String name,Class<?>...parameterTypes)
:返回此class对象对应类的带指定形参的public方法Method[] getMethods()
:返回此class对象所表示的类的所有public方法Method getDeclaredMethod(string name,Class<?>...parameterTypes)
:返回此class对象对应类的带指定形参的方法,与方法访问权限无关Method[] getDeclaredMethods()
:返回此class对象对应类的全部方法,与方法的访问权限无关
获取类成员变量
Field getField(String name)
:返回此class对象对应类的指定名称的public成员变量Field[] getFields()
:返回此class对象对应类的所有public成员变量Field getDeclaredField(String name)
:返回此class对象对应类的指定名称的成员变量,与成员变量访问权限无关Field[] getDeclaredFields()
:返回此class对象对应类的全部成员变量,与成员变量的访问权限无关
获取类注解
<A extends Annotation>A getAnnotation(Class<A>annotationClass)
:尝试获取该class对象对应类上村子的指定类型的Annotation,如果该类型注解不存在,则返回null<A extends Annotation>A getDeclaredAnnotation(Class<A>annotationClass)
:这是Java 8中新增的,该方法获取直接修饰该class对象对应类的指定类型的Annotation,如果不存在,则返回nullAnnotation[] getAnnotations()
:返回修饰该class对象对应类上存在的所有AnnotationAnnotation[] getDeclaredAnnotations()
:返回修饰该Class对象对应类上存在的所有Annotation<A extends Annotation>A[] getAnnotationByType(Class<A>annotationClass)
:该方法的功能与前面介绍的getAnnotation()方法基本相似,但由于Java8增加了重复注解功能,因此需要使用该方法获取修饰该类的指定类型的多个Annotation<A extends Annotation>A[] getDeclaredAnnotationByType(Class<A>annotationClass)
:该方法发功能与前面介绍的getDeclaredAnnotations()方法相似,也是因为Java8的重复注解的功能,需要使用该方法获取直接修饰该类的指定类型的多个Annotation
获取该类内部类
Class<?>[] getDeclaredClasses()
:返回该class队形对应类里包含的全部内部类
获取该类对象所在的外部类
Class<?> getDeclaringClass()
:返回该Class对象对应类所在的外部类
获取该类对象对应类所实现的接口
Class<?>[] getInterfaces()
:返回该Class对象对应类所实现的全部接口
获取该类对象对应类所继承的父类
Class<? super T> getSuperclass()
:返回该Class对象对应类的超类的Class对象
获取该类对象对应类的修饰符、所在包、类名等基本信息
int getModifiers()
:返回此类或接口的所有修饰符,修饰符由public、protected、private、final、static、abstract等对应的常量组成,返回的整数应使用Modifier工具类的方法来解码,才可以获取真是的修饰符Package getPackage()
:获取该类的包String getName()
:以字符串形式返回此CLass对象所表示的类的简称
判断该类是否为接口、枚举、注解类型
boolean isAnnotation()
:返回此class对象是否表示一个注解类型boolean isAnnotationPresent(Class<? extends Annotation>annotationClass)
:判断此Class对象是否使用类Annotation修饰boolean isAnonymousClass()
:返回此class对象是否是一个匿名类boolean isArray()
:返回此class对象是否表示一个数组类boolean isEnum()
:返回此class对象是否表示一个枚举boolean isInterface()
:返回此class对象是否表示一个接口boolean isInstance(Object obj)
:判断obj是否是此class对象的实例,该方法可以完全代替instanceof操作符
- public interface Colorable {
- public void value();
- }
- public class ClassInfo {
- public static void main(String[] args) throws NoSuchMethodException, SecurityException {
- Class<Colorable> cls=Colorable.class;
- System.out.println(cls.getMethod("value"));
- System.out.println(cls.isAnnotation());
- System.out.println(cls.isInterface());
- }
- }
结果
- public abstract void com.em.Colorable.value()
- false
- true
Java8中新增的方法参数反射
int getParameterCount()
:获取该构造器或方法的形参个数Parameter[] getParameters()
:获取该构造器或方法的所有形参getModifiers()
:获取修饰该形参的修饰符String getName()
:获取形参名Type getParameterizedType()
:获取带泛型的形参类型Class<?>getType()
:获取形参类型boolean isNamePresent()
:该方法返回该类的class文件中是否包含了方法的形参名信息boolean isVarArgs()
:该方法用于判断该参数是否为个数可变的形参
- public class Test {
- public void getInfo(String str,List<String>list){
- System.out.println("成功");
- }
- }
- public class ClassInfo {
- public static void main(String[] args) throws NoSuchMethodException, SecurityException {
- Class<Test> cls=Test.class;
- Method med=cls.getMethod("getInfo", String.class,List.class);
- System.out.println(med.getParameterCount());
- Parameter[] params=med.getParameters();
- System.out.println(params.length);
- for(Parameter par:params){
- System.out.println(par.getName());
- System.out.println(par.getType());
- System.out.println(par.getParameterizedType());
- }
- }
- }
结果
- 2
- 2
- arg0
- class java.lang.String
- class java.lang.String
- arg1
- interface java.util.List
- java.util.List<java.lang.String>
反射生成对象
- 使用Class对象的newInstance()方法创建Class对象的实例,该方法要求要有默认构造器(比较常用)
- 先使用Class对象获取指定的Constructor对象,在调用Constructor对象的newInstance()方法来创建该Class对象对应类的实例
反射调用方法
Object invoke(Object obj,Object...args)
:该方法中的obj是执行该方法的主调,后面的args是执行该方法时传入该方法的实参
- public class Test {
- public Test(String str) {
- System.out.println(str);
- }
- public void getInfo(String str){
- System.out.println(str);
- }
- }
- public class ClassInfo {
- public static void main(String[] args) throws Exception {
- Class<Test> cls=Test.class;
- Constructor<Test>construct=cls.getConstructor(String.class);
- Test test=construct.newInstance("初始化");
- Method med=cls.getMethod("getInfo", String.class);
- med.invoke(test, "调用方法成功");
- }
- }
结果
- 初始化
- 调用方法成功
接下来看官仔细看下面的栗子
- public class Test {
- public Test(String str) {
- System.out.println(str);
- }
- //私有方法
- private void getInfo(String str){
- System.out.println(str);
- }
- }
- public class ClassInfo {
- public static void main(String[] args) throws Exception {
- Class<Test> cls=Test.class;
- Constructor<Test>construct=cls.getConstructor(String.class);
- Test test=construct.newInstance("初始化");
- //为啥使用这个方法呢?
- Method med=cls.getDeclaredMethod("getInfo", String.class);
- //为啥使用这个方法呢?
- med.setAccessible(true);
- med.invoke(test, "调用方法成功");
- }
- }
结果
- 初始化
- 调用方法成功
setAccessible(boolean flag):将值设为true,指示该Method在使用是应该取消Java语言的访问权限检查
访问成员变量值
getXxx(Object obj)
:获取obj对象的该成员变量的值。此处的Xxx对应8种基本类型,如果该成员变量的类型是引用类型的,则去掉Xxx部分setXxx(Object obj,Xxx val)
:将obj对象的该成员变量设置为val值。此处的Xxx对应8中基本类型,如果该成员变量的类型是引用类型,则取消set后面的Xxx
以上两个方法可以方法所有的成员变量,包括private的私有成员变量
- public class Test {
- private int num;
- public Test(String str) {
- System.out.println(str);
- }
- private void getInfo(String str){
- System.out.println(str);
- }
- public int getNum() {
- return num;
- }
- public void setNum(int num) {
- this.num = num;
- }
- }
- public class ClassInfo {
- public static void main(String[] args) throws Exception {
- Class<Test> cls=Test.class;
- Constructor<Test>construct=cls.getConstructor(String.class);
- Test test=construct.newInstance("初始化");
- Method med=cls.getDeclaredMethod("getInfo", String.class);
- med.setAccessible(true);
- med.invoke(test, "调用方法成功");
- Field fld=cls.getDeclaredField("num");
- fld.setAccessible(true);
- fld.setInt(test, 12);
- System.out.println(fld.getInt(test));
- }
- }
结果
- 初始化
- 调用方法成功
- 12
操作数组
java.lang.reflect包下有一个Array类,其可以动态创建数组
static Object newInstance(Class<?>componentType,int...length)
:创建一个具有指定的元素类型、指定维度的新数组
static xxx getXxx(Object array,int index)
:返回array数组中第index个元素。其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为get()
static void setXxx(Object array,int index,xxx val)
:将array数组中低index 个元素的值设为val,其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为set()
- public class ArrayInfo {
- public static void main(String[] args) {
- Object arrays=Array.newInstance(String.class, 3);
- Array.set(arrays, 0, "第一个");
- Array.set(arrays, 1, "第二个");
- Array.set(arrays, 2, "第三个");
- System.out.println(Array.get(arrays, 2));
- }
- }
Java反射获取类和对象信息全解析的更多相关文章
- Java 反射 分析类和对象
Java 反射 分析类和对象 @author ixenos 摘要:优化程序启动策略.在运行时使用反射分析类的结构和对象 优化程序启动策略 在启动时,包含main方法的类被加载.它会加载所有它需要的类. ...
- java反射获取类的成员函数,成员变量,构造函数
package com.imooc.reflect;import javax.sound.midi.Soundbank;import java.lang.reflect.Constructor;imp ...
- Java反射获取类对象的三种方式
package demo01; /* * 获取一个类的class文件对象的三种方式 * 1.对象获取 * 2.类名获取 * 3.Class类的静态方法获取 */ public class Reflec ...
- java反射获取类的类名、属性名、属性类型、方法、执行方法、构造函数
public class Demo02 { @SuppressWarnings("all") public static void main(String[] args) thro ...
- java 反射获取类的属性 类型 名称和值
/** * 获取属性类型(type),属性名(name),属性值(value)的map组成的list * */ private List getFiledsInfo(Object o){ Field[ ...
- java 反射获取类的静态属性值
public class AppTest { private NodeClass nodeClass; public static String hehe = "hehe"; pu ...
- php反射获取类和方法中的注释
通过php中的反射机制,获取该类的文档注释,再通过获取其所有的方法,获取方法的注释 所用到的主要类及其方法 ReflectionClass ReflectionClass::getDocComment ...
- 利用Java反射根据类的名称获取属性信息和父类的属性信息
代码: import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java ...
- Java反射学习-1 - 反射获取类的属性,方法,构造器
新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...
随机推荐
- iOS-UI控件精讲之UILabel
UILabel(标签)应该是iOS中最基本的一个控件了,也是使用频率最高的,经常用来展示一段不可编辑的文本. UILabel继承于UIView,下面是一些常用的属性,包含继承于UIView的属性. 1 ...
- 【POJ1707】【伯努利数】Sum of powers
Description A young schoolboy would like to calculate the sum for some fixed natural k and different ...
- Linux的more、less
2.more 文件内容或输出查看工具: more 是我们最常用的工具之一,最常用的就是显示输出的内容,然后根据窗口的大小进行分页显示,然后还能提示文件的百分比: de>[root@localho ...
- [lua]原来这才是表驱动的正确表达方式
曾经写了个很煞笔的脚本模拟switch..case语法形式.[lua]尝试一种Case语法糖 而今实际项目应用中突发,原来这才是正确的表驱动方式表达.如下所贴: function event_do( ...
- nginx利用limit模块设置IP并发防CC攻击
nginx利用limit模块设置IP并发防CC攻击 分类: 系统2013-01-21 09:02 759人阅读 评论(0) 收藏 举报 来源:http://blog.xencdn.net/nginx- ...
- 【原创】Android 对话框的使用
对话框即Dialog .google的官方解释:A dialog is usually a small window that appears in front of the current Acti ...
- php约瑟夫环
<?php function popChar($str , $m , $current = 0){ $number = count($str); $num = 1; if(count($str) ...
- 数据库基本概念-oracle介绍
甲骨文公司,全称甲骨文股份有限公司是全球最大的企业软件公司,总部位于美国加利福尼亚州的红木滩.甲骨文是继Microsoft及IBM后,全球收入第三多的软件公司.甲骨文公司1989年正式进入中国市场.重 ...
- Lambda表达式, 可以让我们的代码更优雅.
在C#中, 适当地使用Lambda表达式, 可以让我们的代码更优雅. 通过lambda表达式, 我们可以很方便地创建一个delegate: 下面两个语句是等价的 Code highlighting p ...
- JSP特点
建立在servlet规范功能之上的动态网页技术. JSP文件在用户第一次请求时,会被编译成servlet,然后由servlet处理用户的请求.所以JSP可以看成运行时servlet. 1).将内容的生 ...