Java反射机制常用方法介绍

来源:互联网 发布:磁条读写器软件 编辑:程序博客网 时间:2024/05/23 02:00
最近恰好用到反射机制,我把相关的知识整理了一下贴在下面。

〇、 Java反射机制简介

在运行状态中,对任意一个类,都能够知道这个类的所有属性和方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。Java reflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。Java 的这一特性非常强大,并且是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的。

但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。

一、测试代码

首先看测试用的Student类与main函数

Student:

import java.io.Serializable;public class Student implements Serializable,Cloneable {    private String name;    private static final String DEFAULT_NAME = "DEFAULT_NAME";    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Student() {        this.name = DEFAULT_NAME;    }    public Student(String name) {        this.name = name;    }    public Object clone() {        Student o = null;        try {            o = (Student) super.clone();        } catch (CloneNotSupportedException e) {            e.printStackTrace();        }        return o;    }}

main函数部分:

import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class Main {    public static void main(String[] args) {        Student student1 = new Student("aaa");        System.out.println(student1.getClass().getName());        try {            // 下面三种获得Class的方法效果是一样的。            Class cls1 = Class.forName(student1.getClass().getName());            Class cls2=Student.class;            Class cls3=student1.getClass();            System.out.println("\n获取属性:");            Field[] fields = cls1.getDeclaredFields();            for(Field field:fields){                String str="";                str+=(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等                str+=(field.getType().getSimpleName() + " ");//属性的类型的名字                str+=(field.getName()+";");//属性的名字+回车                System.out.println(str);            }//            for(Field field: fields){//                System.out.println(field);//            }            System.out.println("\n获取方法:");            Method[] methods = cls1.getMethods();            for (Method method : methods) {                System.out.println(method);            }            System.out.println("\n创建新对象,然后调用方法:");            Object object=cls1.newInstance();            Method getNameMethod=cls1.getMethod("getName");            String msg=(String)getNameMethod.invoke(object);// 此时还是默认name            System.out.println(msg);            // 注意后面跟变量类型            Method setNameMethod=cls1.getMethod("setName", String.class);            setNameMethod.invoke(object,"new name"); // 执行setName更新name            msg=(String)getNameMethod.invoke(object);            System.out.println(msg);        // 获取实例的方法2            Student newStu=(Student)cls1.newInstance();            System.out.println(newStu.getName());            newStu.setName("hhhh");            System.out.println(newStu.getName());        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }  catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }    }}

**

二、 反射常用功能及实现

**
2.1 通过对象,获取该对象的包+类名
如:

Student student1 = new Student("aaa");System.out.println(student1.getClass().getName());

2.2 利用反射获取类

// 下面三种获得Class的方法效果是一样的。Class cls1 = Class.forName(student1.getClass().getName());Class cls2=Student.class;Class cls3=student1.getClass();

2.3 获取类中的属性

Field[] fields = cls1.getDeclaredFields();for(Field field:fields){     String str="";     str+=(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等     str+=(field.getType().getSimpleName() + " ");//属性的类型的名字     str+=(field.getName()+";");//属性的名字+回车     System.out.println(str);}

运行结果:

private String name;private static final String DEFAULT_NAME;

2.4 获取类中的方法

Method[] methods = cls1.getMethods();for (Method method : methods) {    System.out.println(method);}

运行结果:

public java.lang.Object Student.clone()public java.lang.String Student.getName()public void Student.setName(java.lang.String)public final void java.lang.Object.wait() throws java.lang.InterruptedExceptionpublic final void java.lang.Object.wait(long,int) throws java.lang.InterruptedExceptionpublic final native void java.lang.Object.wait(long) throws java.lang.InterruptedExceptionpublic boolean java.lang.Object.equals(java.lang.Object)public java.lang.String java.lang.Object.toString()public native int java.lang.Object.hashCode()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.5 创建新的实例,并且调用类中的方法

// Object object=cls1.newInstance();Method getNameMethod=cls1.getMethod("getName");String msg=(String)getNameMethod.invoke(object);// 此时还是默认nameSystem.out.println(msg);// 注意后面跟变量类型Method setNameMethod=cls1.getMethod("setName",String.class);setNameMethod.invoke(object,"new name");// 执行setName更新namemsg=(String)getNameMethod.invoke(object);System.out.println(msg);// 获取实例的方法2Student newStu=(Student)cls1.newInstance();System.out.println(newStu.getName());newStu.setName("hhhh");System.out.println(newStu.getName());

运行结果:

DEFAULT_NAMEnew nameDEFAULT_NAMEhhhh
0 0
原创粉丝点击