反射可以解决在编译时无法预知对象和类是属于那个类的,要根据程序运行时的信息才能知道该对象和类的信息的问题。

在两个人协作开发时,你只要知道对方的类名就可以进行初步的开发了。

获取类对象

  • 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,如果不存在,则返回null
  • Annotation[] getAnnotations():返回修饰该class对象对应类上存在的所有Annotation
  • Annotation[] 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反射获取类和对象信息全解析的更多相关文章

  1. Java 反射 分析类和对象

    Java 反射 分析类和对象 @author ixenos 摘要:优化程序启动策略.在运行时使用反射分析类的结构和对象 优化程序启动策略 在启动时,包含main方法的类被加载.它会加载所有它需要的类. ...

  2. java反射获取类的成员函数,成员变量,构造函数

    package com.imooc.reflect;import javax.sound.midi.Soundbank;import java.lang.reflect.Constructor;imp ...

  3. Java反射获取类对象的三种方式

    package demo01; /* * 获取一个类的class文件对象的三种方式 * 1.对象获取 * 2.类名获取 * 3.Class类的静态方法获取 */ public class Reflec ...

  4. java反射获取类的类名、属性名、属性类型、方法、执行方法、构造函数

    public class Demo02 { @SuppressWarnings("all") public static void main(String[] args) thro ...

  5. java 反射获取类的属性 类型 名称和值

    /** * 获取属性类型(type),属性名(name),属性值(value)的map组成的list * */ private List getFiledsInfo(Object o){ Field[ ...

  6. java 反射获取类的静态属性值

    public class AppTest { private NodeClass nodeClass; public static String hehe = "hehe"; pu ...

  7. php反射获取类和方法中的注释

    通过php中的反射机制,获取该类的文档注释,再通过获取其所有的方法,获取方法的注释 所用到的主要类及其方法 ReflectionClass ReflectionClass::getDocComment ...

  8. 利用Java反射根据类的名称获取属性信息和父类的属性信息

    代码: import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java ...

  9. Java反射学习-1 - 反射获取类的属性,方法,构造器

    新建一个Person类 package cn.tx.reflect; /** * 注解初步了解 * @author Administrator * */ public class Person { p ...

随机推荐

  1. ios开发中MVC模式的理解

    MVC是80年代出现的一种软件设计模式,是模型(model),视图(view)和控制(Controller)的缩写. 其中Model的主要功能包括业务逻辑的处理以及数据的访问,这是应用程序的主体部分. ...

  2. DFS的基础训练清单

    HDU 1010  (AC) HDU 1015    (AC) HDU 1016     (AC) HDU 1172   (AC) HDU 1312   (AC) POJ 2362  (AC,1011 ...

  3. mysql远程连接

    多人开发时,每人一份程序文件.但是有时需要公用一个份数据库.这时就需要数据库能远程连接. 现在以mysql为例演示一下. 这里远程连接可以 1.允许固定客户端ip登陆. select host,use ...

  4. 用Django搭建个人博客—(3)

    今日主题 定义博客文章和评论的的数据库定义 定义操作这几个Model的后台数据 User表 USER_STATUS = ( ('active', u'激活'), ('suspended', u'禁用' ...

  5. 从string.size()和string.length()聊到长度的问题和一个关于数据结构定义的技巧

    最近工作中要查看一下string的长度,然后忘了是哪个函数,所以去网上搜了一搜,决定把网上学的和其他的一些有关长度的东西在这里汇总一下, 然后就有了此帖. string 是从c语言的char数组的概念 ...

  6. 学习Swift -- 数组(Array) - 持续更新

    集合类型--数组 Array是Swift中的一种集合类型:数组,数组是使用有序列表储存同一类型的多个值,与OC的NSArray的最大不同是,Swift的数组是值类型,OC的数组是引用类型 声明数组的方 ...

  7. EntityFramework 和 linq 判断是否在指定时间段内的方法

    EntityFramework: System.Data.Objects.EntityFunctions.DiffDays(DateTime.Now, inputTime)判断当前时间与指定时间相差多 ...

  8. JAVA抽象类和接口的深入探讨

    Java 语言中,抽象类(abstract class) 和接口(interface) 是抽象思想的两种体现形式.初学者很容易把这两者搞混,所以Java面试中考抽象类和接口的区别的面试题也常有出现的. ...

  9. vim自动补全

    Vim 中使用 OmniComplete 为 C/C++ 自动补全 OmniComplete 并不是插件的名字,而是 Vim 众多补全方式中的一种(全能补全).说白了 OmniComplete 其实就 ...

  10. [CF Round #294 div2] E. A and B and Lecture Rooms 【树上倍增】

    题目链接:E. A and B and Lecture Rooms 题目大意 给定一颗节点数10^5的树,有10^5个询问,每次询问树上到xi, yi这两个点距离相等的点有多少个. 题目分析 若 x= ...