Java-反射机制学习

反射机制是Java的一个重要性,它使得Java语言具有了动态特性。比如说,可以在代码中动态地获取某个类的信息,生成它的实例、获取其成员变量、调用它的方法。下面通过几个示例来演示反射机制的作用与用法。

示例1.获取类的信息

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

/*
 * @Date 20160223
 * 演示了如何通过反射机制获取指定类的构造方法、超类、接口、域和方法
 */
public class ClassInfoCollector {

    public void run() throws Exception {
        Class c = Class.forName("java.lang.Long");
        Class [] cs = {java.lang.String.class};
        System.out.println("\n-------------------------------\n");

        Constructor cs1 = c.getConstructor(cs);
        System.out.println("1、通过参数获取指定Class对象的构造方法:");
        System.out.println(cs1.toString());

        Constructor cs2 = c.getDeclaredConstructor(cs);
        System.out.println("2、通过参数获取指定Class对象所表示的类或接口的构造方法:");
        System.out.println(cs2.toString());

        Constructor cs3 = c.getEnclosingConstructor();
        System.out.println("3、获取本地或匿名类Constructor 对象,它表示基础类的立即封闭构造方法。");
        if (cs3 != null) System.out.println(cs3.toString());
        else System.out.println("-- 没有获取到任何构造方法!");

        Constructor[] css = c.getConstructors();
        System.out.println("4、获取指定Class对象的所有构造方法:");
        for (int i = 0; i < css.length; i++) {
            System.out.println(css[i].toString());
        }

        System.out.println("\n-------------------------------\n");

        Type [] tys1 = c.getGenericInterfaces();
        System.out.println("1、返回直接实现的接口:");
        for (int i = 0; i < tys1.length; i++) {
            System.out.println(tys1[i].toString());
        }

        Type type1 = c.getGenericSuperclass();
        System.out.println("2、返回直接超类:");
        System.out.println(type1.toString());

        Class [] cls1 = c.getClasses();
        System.out.println("3、返回超类和所有实现的接口:");
        for (int i = 0; i < cls1.length; i++) {
            System.out.println(cls1[i].toString());
        }

        Class [] cls2 = c.getInterfaces();
        System.out.println("4、实现的接口");
        for (int i = 0; i < cls2.length; i++) {
            System.out.println(cls2[i].toString());
        }

        System.out.println("\n-------------------------------\n");
        Field [] fds1 = c.getFields();
        System.out.println("1、类或接口的所有可访问公共字段:");
        for (int i = 0; i < fds1.length; i++) {
            System.out.println(fds1[i].toString());
        }

        Field [] fds2 = c.getDeclaredFields();
        System.out.println("2、类或接口所声明的所有字段:");
        for (int i = 0; i < fds2.length; i++) {
            System.out.println(fds2[i].toString());
        }

        Field fd1 = c.getField("MIN_VALUE");
        System.out.println("3、类或接口的指定已声明指定公共成员字段:");
        System.out.println(fd1.toString());

        Field fd2 = c.getDeclaredField("serialVersionUID");
        System.out.println("4、类或接口的指定已声明指定字段:");
        System.out.println(fd2.toString());

        System.out.println("\n-------------------------------\n");

        Method [] md1 = c.getMethods();
        System.out.println("1、返回类所有的公共成员方法:");
        for (int i = 0; i < md1.length; i++) {
            System.out.println(md1[i].toString());
        }

        Method [] md2 = c.getDeclaredMethods();
        System.out.println("2、返回类所有的成员方法:");
        for (int i = 0; i < md2.length; i++) {
            System.out.println(md2[i].toString());
        }

        Method m3 = c.getMethod("longValue", new Class[]{});
        System.out.println("3、返回指定公共成员方法:");
        System.out.println(m3.toString());
        }

    public static void main(String args[]) throws Exception {
        ClassInfoCollector cic = new ClassInfoCollector();
        cic.run();
    }
}

输出如下:

-------------------------------

1、通过参数获取指定Class对象的构造方法:
public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException
2、通过参数获取指定Class对象所表示的类或接口的构造方法:
public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException
3、获取本地或匿名类Constructor 对象,它表示基础类的立即封闭构造方法。
-- 没有获取到任何构造方法!
4、获取指定Class对象的所有构造方法:
public java.lang.Long(long)
public java.lang.Long(java.lang.String) throws java.lang.NumberFormatException

-------------------------------

1、返回直接实现的接口:
java.lang.Comparable<java.lang.Long>
2、返回直接超类:
class java.lang.Number
3、返回超类和所有实现的接口:
4、实现的接口
interface java.lang.Comparable

-------------------------------

1、类或接口的所有可访问公共字段:
public static final long java.lang.Long.MIN_VALUE
public static final long java.lang.Long.MAX_VALUE
public static final java.lang.Class java.lang.Long.TYPE
public static final int java.lang.Long.SIZE
public static final int java.lang.Long.BYTES
2、类或接口所声明的所有字段:
public static final long java.lang.Long.MIN_VALUE
public static final long java.lang.Long.MAX_VALUE
public static final java.lang.Class java.lang.Long.TYPE
private final long java.lang.Long.value
public static final int java.lang.Long.SIZE
public static final int java.lang.Long.BYTES
private static final long java.lang.Long.serialVersionUID
3、类或接口的指定已声明指定公共成员字段:
public static final long java.lang.Long.MIN_VALUE
4、类或接口的指定已声明指定字段:
private static final long java.lang.Long.serialVersionUID

-------------------------------

1、返回类所有的公共成员方法:
public static int java.lang.Long.numberOfLeadingZeros(long)
public static int java.lang.Long.numberOfTrailingZeros(long)
public static int java.lang.Long.bitCount(long)
public boolean java.lang.Long.equals(java.lang.Object)
public java.lang.String java.lang.Long.toString()
public static java.lang.String java.lang.Long.toString(long,int)
public static java.lang.String java.lang.Long.toString(long)
public int java.lang.Long.hashCode()
public static int java.lang.Long.hashCode(long)
public static long java.lang.Long.min(long,long)
public static long java.lang.Long.max(long,long)
public static long java.lang.Long.reverseBytes(long)
public int java.lang.Long.compareTo(java.lang.Object)
public int java.lang.Long.compareTo(java.lang.Long)
public static java.lang.Long java.lang.Long.getLong(java.lang.String,java.lang.Long)
public static java.lang.Long java.lang.Long.getLong(java.lang.String,long)
public static java.lang.Long java.lang.Long.getLong(java.lang.String)
public byte java.lang.Long.byteValue()
public short java.lang.Long.shortValue()
public int java.lang.Long.intValue()
public long java.lang.Long.longValue()
public float java.lang.Long.floatValue()
public double java.lang.Long.doubleValue()
public static java.lang.Long java.lang.Long.valueOf(long)
public static java.lang.Long java.lang.Long.valueOf(java.lang.String,int) throws java.lang.NumberFormatException
public static java.lang.Long java.lang.Long.valueOf(java.lang.String) throws java.lang.NumberFormatException
public static java.lang.String java.lang.Long.toHexString(long)
public static int java.lang.Long.compare(long,long)
public static java.lang.Long java.lang.Long.decode(java.lang.String) throws java.lang.NumberFormatException
public static long java.lang.Long.reverse(long)
public static long java.lang.Long.sum(long,long)
public static int java.lang.Long.compareUnsigned(long,long)
public static long java.lang.Long.divideUnsigned(long,long)
public static long java.lang.Long.highestOneBit(long)
public static long java.lang.Long.lowestOneBit(long)
public static long java.lang.Long.parseLong(java.lang.String,int) throws java.lang.NumberFormatException
public static long java.lang.Long.parseLong(java.lang.String) throws java.lang.NumberFormatException
public static long java.lang.Long.remainderUnsigned(long,long)
public static long java.lang.Long.rotateLeft(long,int)
public static long java.lang.Long.rotateRight(long,int)
public static int java.lang.Long.signum(long)
public static java.lang.String java.lang.Long.toBinaryString(long)
public static java.lang.String java.lang.Long.toOctalString(long)
public static java.lang.String java.lang.Long.toUnsignedString(long)
public static java.lang.String java.lang.Long.toUnsignedString(long,int)
public static long java.lang.Long.parseUnsignedLong(java.lang.String) throws java.lang.NumberFormatException
public static long java.lang.Long.parseUnsignedLong(java.lang.String,int) throws java.lang.NumberFormatException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
2、返回类所有的成员方法:
public static int java.lang.Long.numberOfLeadingZeros(long)
public static int java.lang.Long.numberOfTrailingZeros(long)
public static int java.lang.Long.bitCount(long)
public boolean java.lang.Long.equals(java.lang.Object)
public java.lang.String java.lang.Long.toString()
public static java.lang.String java.lang.Long.toString(long,int)
public static java.lang.String java.lang.Long.toString(long)
public int java.lang.Long.hashCode()
public static int java.lang.Long.hashCode(long)
public static long java.lang.Long.min(long,long)
public static long java.lang.Long.max(long,long)
public static long java.lang.Long.reverseBytes(long)
public int java.lang.Long.compareTo(java.lang.Object)
public int java.lang.Long.compareTo(java.lang.Long)
public static java.lang.Long java.lang.Long.getLong(java.lang.String,java.lang.Long)
public static java.lang.Long java.lang.Long.getLong(java.lang.String,long)
public static java.lang.Long java.lang.Long.getLong(java.lang.String)
public byte java.lang.Long.byteValue()
public short java.lang.Long.shortValue()
public int java.lang.Long.intValue()
public long java.lang.Long.longValue()
public float java.lang.Long.floatValue()
public double java.lang.Long.doubleValue()
public static java.lang.Long java.lang.Long.valueOf(long)
public static java.lang.Long java.lang.Long.valueOf(java.lang.String,int) throws java.lang.NumberFormatException
public static java.lang.Long java.lang.Long.valueOf(java.lang.String) throws java.lang.NumberFormatException
public static java.lang.String java.lang.Long.toHexString(long)
public static int java.lang.Long.compare(long,long)
public static java.lang.Long java.lang.Long.decode(java.lang.String) throws java.lang.NumberFormatException
static void java.lang.Long.getChars(long,int,char[])
public static long java.lang.Long.reverse(long)
static int java.lang.Long.stringSize(long)
public static long java.lang.Long.sum(long,long)
public static int java.lang.Long.compareUnsigned(long,long)
public static long java.lang.Long.divideUnsigned(long,long)
public static long java.lang.Long.highestOneBit(long)
public static long java.lang.Long.lowestOneBit(long)
public static long java.lang.Long.parseLong(java.lang.String,int) throws java.lang.NumberFormatException
public static long java.lang.Long.parseLong(java.lang.String) throws java.lang.NumberFormatException
public static long java.lang.Long.remainderUnsigned(long,long)
public static long java.lang.Long.rotateLeft(long,int)
public static long java.lang.Long.rotateRight(long,int)
public static int java.lang.Long.signum(long)
public static java.lang.String java.lang.Long.toBinaryString(long)
public static java.lang.String java.lang.Long.toOctalString(long)
public static java.lang.String java.lang.Long.toUnsignedString(long)
public static java.lang.String java.lang.Long.toUnsignedString(long,int)
static java.lang.String java.lang.Long.toUnsignedString0(long,int)
static int java.lang.Long.formatUnsignedLong(long,int,char[],int,int)
public static long java.lang.Long.parseUnsignedLong(java.lang.String) throws java.lang.NumberFormatException
public static long java.lang.Long.parseUnsignedLong(java.lang.String,int) throws java.lang.NumberFormatException
private static java.math.BigInteger java.lang.Long.toUnsignedBigInteger(long)
3、返回指定公共成员方法:
public long java.lang.Long.longValue()

=========================

可以看到,能够获取的信息非常全面。

示例2.动态调用类的方法

import java.lang.reflect.Method;
import java.lang.reflect.Type;
/*
 * @Date 20160223
 * 演示了如何通过反射机制调用指定类的方法,以add()和echo()为例
 */
public class MethodInvoker {
     public int add(int param1, int param2) {
            return param1 + param2;
        }

        public String echo(String msg) {
            return "echo: " + msg;
        }

        public static void main(String[] args) throws Exception {
            Class<?> classType = MethodInvoker.class;
            Object invokeTester = classType.newInstance();

            //获取InvokeTester类的add()方法
            Method addMethod = classType.getMethod("add", new Class[]{int.class, int.class});
            //调用invokeTester对象上的add()方法
            Object result = addMethod.invoke(invokeTester, new Object[]{new Integer(100), new Integer(200)});
            System.out.println((Integer) result);

            //获取InvokeTester类的echo()方法
            Method echoMethod = classType.getMethod("echo", new Class[]{String.class});
            //调用invokeTester对象的echo()方法
            result = echoMethod.invoke(invokeTester, new Object[]{"Hello"});
            System.out.println((String) result);
        }
    }

输出如下:

300
echo: Hello

===================================

在示例2中,首先使用classType.newInstance()生成了该类的对象,然后获取了其add和echo方法,最后调用了这两个方法。

示例3.访问对象的成员变量

import java.lang.reflect.Field;

/*
 * @Date 20160223
 * 演示了如何通过java.lang.reflect.Field类的get和set方法动态调整对象的域
 */

public class FieldModifier {
    public double x;
    public double y;
    private double z;

    public static void main(String args[]) throws NoSuchFieldException, IllegalAccessException {
        Class c = FieldModifier.class;
        Field xf = c.getField("x");
        Field yf = c.getField("y");
        Field zf = c.getDeclaredField("z");

        FieldModifier obj = new FieldModifier();

        //变更成员x值
        System.out.println("变更前x=" + xf.get(obj));
        xf.set(obj, 1.1);
        System.out.println("变更后x=" + xf.get(obj));

        //变更成员y值
        System.out.println("变更前y=" + yf.get(obj));
        yf.set(obj, 2.1);
        System.out.println("变更后y=" + yf.get(obj));       

        //变更成员z值
        System.out.println("变更前z=" + zf.get(obj));
        zf.set(obj, 3.1);
        System.out.println("变更后z=" + zf.get(obj));
    }
}

输出如下:

变更前x=0.0
变更后x=1.1
变更前y=0.0
变更后y=2.1
变更前z=0.0
变更后z=3.1

==================

示例3通过Field的get和set方法访问成员变量,包括私有成员。

示例4.动态创建和调整数组

import java.lang.reflect.Array;
/*
 * @Date 20160223
 * 演示了如何通过java.lang.reflect.Array动态创建和调整数组
 *
 */
public class DynamicArrayTest2 {

    public static void main(String args[]) {
        int[] dims = new int[]{5, 10, 15};//指定即将创造的数组在每一维度上的长度
        //创建一个具有指定的组件类型和维度的新数组。
        Object array = Array.newInstance(Integer.TYPE, dims);

        Object arrayObj = Array.get(array, 3);//第array[][][3]个5*10的整型[][]数组
        Class<?> cls = arrayObj.getClass().getComponentType();
        System.out.println(cls);

        arrayObj = Array.get(arrayObj, 5);//第array[][5][3]个整型[]数组
        Array.setInt(arrayObj, 10, 37);//第array[10][5][3]个整型数,设置其值为37
        int arrayCast[][][] = (int[][][]) array;
        System.out.println(arrayCast[3][5][10]);
    }
}

输出如下:

class [I
37

=========================

利用java.lang.reflect.Array来实现数组的创建与操作。

时间: 2024-10-12 20:48:53

Java-反射机制学习的相关文章

JAVA反射机制—学习总结

最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象. 什么是反射机制? "JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制."我们通过一些例子,更好理解反射机制.Class类 我们知道Java是一门面向对象

JAVA反射机制学习随笔

JAVA反射机制是用于在运行时动态的获取类的信息或者方法,属性,也可以用来动态的生成类,由于所有类都是CLASS的子类,我们可以用一个CLASS类的实例来实例化各种类 例如: Class<?> class1 = null; Class<?> class2 = null; //写法1, 可能抛出 ClassNotFoundException [多用这个写法] class1 = Class.forName("cn.lee.demo.Person"); System.

Java反射机制学习

Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的.这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制. Java 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类. 在运行时构造任意一个类的对象. 在运行时判断任意一个类所具有的成员变量和方法. 在运行时调用任意一个对象的

Java反射机制学习笔记

Java反射机制 简介 通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理可以原生实现AOP中的方法拦截功能.通过反射获取到的Java类内部结构后再进行运用,和直接运用这个类效果相同,但额外的提供了运行时刻的灵活性.反射的最大一个弊端是性能比较差.相同的操作,用反射API所需的时间大概比直接的使用要慢一两个数量级.可以考虑在适当的时机来使用反射API. 基本用法 Java反射机制主要有两个作用.第一个主要作用是获取程序再运行时刻的内部结构.只需要少量的代码就能便利出一个J

java反射机制学习小结

之前一直对java的反射机制理解得很模糊,今天因为学习spring,所以花了些时间总算把它理顺了,记录一下 另外,推荐读读这篇文章,写的挺好的http://blog.csdn.net/woshixuye/article/details/7700455 class Person { private String name; private int age; // public Person(String name,int age){ // this.name=name; // this.age=a

java反射机制学习:初始反射机制

本人小白一枚,想和大家一起分享我学习java的笔记和心得. 反射机制: 指的是可以于运行时加载.探知.使用编译期间完全未知的类. 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: Class clazz = Class.forName(com.danchel.reflect.User); 加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象

黑马程序员---Java反射机制学习

由现在这个时间补上反射机制的学习笔记,本想报20期的JavaEE班,无奈真担心自己过不去,所以这段时间,一直的复习现在改报21期的吧!! 准备知识:一 1.Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method:    其中class代表的时类对象,    Constructor-类的构造器对象,    Field-类的属性对象,    Method-类的方法对象. 2.在Java中,每个class都有一个相应的Class对象.也就是说,当我们编写一

Thinking in Java---类型信息和java反射机制学习笔记

前面学习的多态给了我们一个很好的承诺:我们编写的代码只要与基类打交道,而不用为每一个新增加的子类写一份代码.但是这种思想在我们想要访问子类自己定义的方法时,就会有问题了.如下面的代码所示: class Base1{ void f(){ System.out.println("Base.f()"); } } class Sub extends Base1{ void f(){ System.out.println("Sub.f()"); } void g(){ Sys

java反射机制学习笔记及例子代码

Java 反射的API 反射中常常用的几个类如下所示: java.lang 包中: --Class 类:代表一个类 Java 中,无论生成某个类的多少个对象,这些对象都会对应同一个 Class 对象 Java.lang.reflect 包中: --Field 类:代表类的成员变量(类的属性) --Method 类:代表类的方法,一个方法对应一个 Method 对象 --Constructor 类:代表类的构造方法 --Array 类:提供动态创建数组,以及访问数组的元素的静态方法 利用反射机制调

Java 反射机制学习资料

Java反射——引言 Java反射——Class对象 Java反射——构造函数 Java反射——字段 Java反射——方法 Java反射——Getter和Setter Java反射——私有字段和私有方法 Java反射——注解 Java反射——泛型 Java反射——数组 Java反射——动态代理 Java反射——类的动态加载和重新加载