java反射的用法

反射(运行时的类信息),在java里面得到了大量的使用,尤其是在一些框架里面(注解等等),多多少少都会用到反射,了解java的反射,对我们以后学习框架和写框架都会起到非常的重要!

Class类与java.lang.reflect类库一起对反射的概念进行了支持,该类库包括了FieId、Method以及Constructor类。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样你就可以使用Constructor创建新的对象,用get()和set()方法读取和修改与FieId对象关联的字段,用invoke()方法调用与Method对象关联的方法,另外还可以调用getFieIds()、getMethods()和getConstructors()等很便利的方法,以返回表示字段、方法以及构造器的对象的数组。

首先,我们创建一个类,代码如下

public class ReflexObject {

    private int a;
    protected int b;
    int c;
    public int d;

    public ReflexObject(){
        super();
    }

    public ReflexObject(int a, int b, int c, int d) {
        super();
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }

    private void setA(int a){
        this.a=a;
        System.out.println("我是公有方法");
    }

    protected void setB(int b){
        this.b=b;
        System.out.println("我是私有方法");
    }

    void setC(int c){
        this.c=c;
        System.out.println("我是包方法");
    }

    public void setD(int d){
        this.d=d;
        System.out.println("我是受保护方法");
    }

    @Override
    public String toString() {
        return "ReflexObject [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";
    }

}

1??通过getConstructors()、getMethods()和getFields()方法获取类里面的信息,代码如下

public static void main(String[] args) {
    Constructor<?>[] constructors = ReflexObject.class.getConstructors();//获取类里面的构造器方法
    Method[] methods = ReflexObject.class.getMethods();//获取类里面的方法
    Field[] fields = ReflexObject.class.getFields();//获取类里面的属性
    for(Constructor<?> c:constructors){
        System.out.println(c.toString());
    }
    System.out.println("-------------------------------");
    for(Method m:methods){
        System.out.println(m.toString());
    }
    System.out.println("-------------------------------");
    for(Field f:fields){
        System.out.println(f.toString());
    }
    System.out.println("-------------------------------");
}

输出结果

可以看到,通过getConstructors()、getMethods()和getFields()方法获取类里面的信息只能是公有的,并且可以获取到父类Object的公有方法。

2??用invoke()方法调用与Method对象关联的方法,代码如下

public static void main(String[] args) {
    ReflexObject rObj=new ReflexObject();
    System.out.println(rObj);
    try {
        Method methodA = ReflexObject.class.getDeclaredMethod("setA", int.class);
        Method methodB = ReflexObject.class.getDeclaredMethod("setB", int.class);
        Method methodC = ReflexObject.class.getDeclaredMethod("setC", int.class);
        Method methodD = ReflexObject.class.getDeclaredMethod("setD", int.class);
        methodA.setAccessible(true);
        methodA.invoke(rObj, 3);
        methodB.setAccessible(true);
        methodB.invoke(rObj, 3);
        methodC.setAccessible(true);
        methodC.invoke(rObj, 3);
        methodD.setAccessible(true);
        methodD.invoke(rObj, 3);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(rObj);
}

因为invoke(obj,args...)是Method方法,并不知道是要那个对象obj执行改方法,必须指定需要修改那个对象obj,传递的参数args

输出结果如下

可以看到,的确是把将属性0都改成了3,执行了方法,甚至是private方法。注意,除了public方法外,其它的都要将setAccessible设置为true,这个大家可以试一下。

3??通过FieId类直接修改属性值

public static void main(String[] args) {
    ReflexObject rObj=new ReflexObject();
    System.out.println(rObj);
    try {
        Field fieldA = ReflexObject.class.getDeclaredField("a");
        Field fieldB = ReflexObject.class.getDeclaredField("b");
        Field fieldC = ReflexObject.class.getDeclaredField("c");
        Field fieldD = ReflexObject.class.getDeclaredField("d");
        fieldA.setAccessible(true);
        fieldA.set(rObj, 3);
        fieldB.setAccessible(true);
        fieldB.set(rObj, 3);
        fieldC.setAccessible(true);
        fieldC.set(rObj, 3);
        fieldD.setAccessible(true);
        fieldD.set(rObj, 3);
    } catch (NoSuchFieldException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(rObj);
}

输出结果

结论和注意点类似2??

4??通过Constructor反射出一个对象,代码如下

public static void main(String[] args) {
    try {
        Constructor<ReflexObject> constructor1 = ReflexObject.class.getDeclaredConstructor();//无参数构造器
        Constructor<ReflexObject> constructor2 = ReflexObject.class.getDeclaredConstructor(int.class,int.class,int.class,int.class);//带参数的构造器
        ReflexObject object1 = constructor1.newInstance();
        ReflexObject object2 = constructor2.newInstance(3,3,3,3);
        System.out.println(object1);
        System.out.println(object2);
    } catch(Exception e) {
        e.printStackTrace();
    }
}

输出结果如下

这里我并没有将setAccessible设置为true,因为我的构造方法都是public,大家可以试一下其它的访问权限。

ok,反射我就写到这里,如果写的有什么问题,大家可以在下面留言,谢谢!

时间: 2024-08-06 23:19:23

java反射的用法的相关文章

Java 反射经常用法演示样例

<pre name="code" class="java">import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; class Point{ int x; private int y; public Point(){ x = 1; y = 2; } public void setX(int x) { thi

java反射--Field用法实践

Field是一个位于java.lang.reflect包下的类,用来描述类的属性信息,功能主要包括: 获取哦大年对象的成员变量类型 对成员变量重新设值 Field类对象: Class.getFields(): 获取类中public类型的属性,返回一个包含某些 Field 对象的数组,该数组包含此 Class 对象所表示的类或接口的所有可访问公共字段getDeclaredFields(): 获取类中所有的属性(public.protected.default.private),但不包括继承的属性,

Java 反射的用法 有关Class类的解释

package com.imooc.test; public class ClassDemo1 { public static void main(String[] args) { Foo fool = new Foo();//foo1就表示出来了 //Foo 这个类也是一个实例对象,Class类的实例对象,如何表示呢 //任何一个类都是Class的实例对象,这个实例对象有三种表示方式 //第一种表示方式---> 实际在告诉我们任何一个类都有一个隐含的静态成员变量class Class cl =

Java反射机制Class类的用法详解

本文转自http://blog.sina.com.cn/s/blog_6c9536b90100rqh4.html,感谢作者 java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息,下面我们来了解一下有关java中Class类的相关知识! java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息. 当一个类或接口被装入的JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象

Java反射机制的用法

Java的反射机制允许你在程序运行的过程中获取类定义的细节.有时候在程序运行的时候才得知要调用哪个方法,这时候反射机制就派上用场了. 获取类 类的获取方法有以下几种: forName().通过Class.forName()获取与字符串向对应的类.比如\lstinline{Class.forName("java.lang.String");}. getClass().每个对象都有这个方法.比如\lstinline{Foo foo; ...; foo.getClass();}. 类名.cl

Java反射

1. 介绍 反射是一种能够在程序运行时动态访问.修改某个类中任意属性和方法的机制. 具体:对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意一个方法和属性 在运行时,当加载完类之后,JVM在堆内存中会自动产生一个Class类型的对象,这个对象包含了完整的类的结构信息 这个Class对象就像一面镜子,透过这个镜子看到类的结构 那么,如何得到这个Class对象呢?以下可否 Class c = new Class(); 答案是不行的,因为Class的构造函数定义为私有

Java反射详解

Java反射详解 分类:java, 基础日期:2012-07-20作者:ticmy 19 反射,是Java中非常重要的一个功能,如果没有反射,可以说很多框架都难以实现. 什么是反射?说白了就是可以通过Java代码获取装载到方法区的类信息的手段. 当装载一个类时,会在方法区产生一个数据结构,该结构中包含着装载的类的相关信息.字节码可以看成是数据流,那么方法区的这种数据结构可以说是字节码数据流的结构化表现.装载的最终产物就是java.lang.Class类的一个对象,它是Java程序与方法区内部数据

Java反射学习总结

广州疯狂软件教育Java培训,iOS培训分享Class类是Reflection API中核心的类,他位于java.lang.Class列出一些常用的方法.- getName() : 获得类的完整名字- getFields() : 获得类的public类型的属性- getDeclaredFields() : 获得类的所有属性- getMethods() : 获得类的public类型的方法- getDeclaredMethods() : 获得类的所有方法- getMethod(String name

Java反射举例

本文参考:http://www.cnblogs.com/yydcdut/p/3845430.html 1.Java反射的基本介绍 Java的反射非常强大,传递class, 可以动态的生成该类.取得这个类的所有信息,包括里面的属性.方法以及构造函数等,甚至可以取得其父类或父接口里面的内容. Java 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法; 生成动态代理. 在