java反射 reflect

反射

反射(Reflection)是Java的语言特征之一,它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。Java反射机制可以动态地创建对象并调用其属性方法等。

Java反射框架主要提供以下功能:

  1. 在运行时判断任意一个对象所需的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断任意一个类所具有的成员变量和方法(甚至可以调用private方法)
  4. 在运行时调用任意一个对象的方法

反射的主要用途

  • 在编译器中。当我们输入一个对象或类并想调用它的属性或方法时,编译器就会列出它的属性或方法,使用的就是反射。
  • 反射最重要的用途就是开发各种通用框架。

反射的基本运用

反射的类一般都在:

java.lang.reflect

获取Class对象

  1. 使用Class类的forName静态方法:

java.lang.Class 中的方法:

public static Class<?> forName(String className) throws ClassNotFoundException

 Class.forName("reflect.Person");
  1. 直接获取某一个对象的Class:
Person.class
  1. 调用某个对象的getClass()方法:

java.lang.Object 中的方法

public final native Class<?> getClass();

Person p1 = new Person();
Class p1Class = p1.getClass();

判断是否为某个类的实例

一般可以使用 instanceof关键字类判断是否为某个类的实例。同时也可以借助反射中Class对象的isInstance()方法类判断是否为某个类的实例,它是一个Native方法。

java.lang.Class

public native boolean isInstance(Object obj);

 Person p1 = new Person();
 boolean b1 = p1 instanceof Person; // true
 boolean b2 = Class.forName("reflect.Person").isInstance(p1); // true
 boolean b3 = Person.class.isInstance(p1); // true
 boolean b4 = p1.getClass().isInstance(p1); // true

创建实例

  1. 使用Class对象的newInstance()方法来创建Class对象类的实例。

java.lang.Class

public T newInstance() throws InstantiationException, IllegalAccessException

Class c = Person.class;
Person p = (Person) c.newInstance();
  1. 先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以使用指定的构造器构造类的实例。
 Class c = Person.class;
 // 使用无参构造器
 Constructor constructor1 = c.getConstructor();
 Person p1 = (Person) constructor1.newInstance();
 //使用带参数的构造器
 Constructor constructor2 =c.getConstructor(String.class);
 Person p2 = (Person) constructor2.newInstance("aa");

获取方法

获取某个Class对象的方法

  • getDeclaredMethods()

返回类或者接口声明的所有方法(包括公共、保护、默认,但不包括继承的方法)。

public Method[] getDeclaredMethods() throws SecurityException
  • getMethods()

返回所有 public 方法,包括继承类的 public 方法

public Method[] getMethods() throws SecurityException
  • getMethod(String name,Class<?>... parameterTypes)

返回特定的方法

 public Method getMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException 

测试

public class Person {
    public String name;


    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String fun01() {
        System.out.println("person fun01" + this.name);
        return "person fun01" + this.name;
    }

    public String fun02(String param) {
        return "person fun02 " + param;
    }


}
public class Student extends Person {
    public double score;

    private String pfun(){
        return "private pfun";
    }
    public String sfun() {
        System.out.println("student sfun");
        return "student sfun";
    }

}

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException {
        Class c = Student.class;
        Method[] methods = c.getMethods();
        System.out.println("=====获取 methods =====");
        for (Method m :methods){
            System.out.println(m);
        }
        Method[] declaredMethods = c.getDeclaredMethods();
        System.out.println("=====获取 declareMethods =====");
        for(Method m:declaredMethods){
            System.out.println(m);
        }
        System.out.println("=====获取 某个方法 =====");
        Method m = c.getMethod("sfun");
        System.out.println(m);
    }

运行结果如下:

=====获取 methods =====
public java.lang.String reflect.Student.sfun()
public java.lang.String reflect.Person.fun01()
public java.lang.String reflect.Person.fun02(java.lang.String)
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 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()
=====获取 declareMethods =====
public java.lang.String reflect.Student.sfun()
private java.lang.String reflect.Student.pfun()
=====获取 某个方法 =====
public java.lang.String reflect.Student.sfun()

调用方法

获取方法之后就可以用 invoke()来调用获取的方法:

java.lang.reflect.Method

public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException

下面是调用方法的实例:

    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class c = Student.class;
        // 创建一个实例
        Object obj = c.newInstance();
        Method sfun = c.getMethod("sfun");
        Object result1 = sfun.invoke(obj);
        System.out.println(result1);
        Object result2 = c.getMethod("voidFun", String.class).invoke(obj, "param");
        System.out.println(result2);
        Method p = c.getDeclaredMethod("pfun");
        //设置权限
        p.setAccessible(true);
        Object result3 = p.invoke(obj);
        System.out.println(result3);
    }

结果:

student sfun
result student sfun
void funparam
null
private pfun
public class Student  {

    private String pfun(){
        return "private pfun";
    }
    public String sfun() {
        System.out.println("student sfun");
        return "result student sfun";
    }
    public void voidFun(String para){
        System.out.println("void fun"+para);
    }

}

获取类的成员变量

同获取方法类似


Field[] getFields() throws SecurityException

Field getField(String name)
        throws NoSuchFieldException, SecurityException
        
Field[] getDeclaredFields() throws SecurityException

Field getDeclaredField(String name)
        throws NoSuchFieldException, SecurityException
        
        

使用ReflectASM反射

这个效率高一些

导包:

  <dependency>
      <groupId>com.esotericsoftware</groupId>
      <artifactId>reflectasm</artifactId>
      <version>1.11.7</version>
  </dependency>

执行方法

    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Class clazz = Person.class;
        FieldAccess fieldAccess = FieldAccess.get(clazz);
        MethodAccess methodAccess = MethodAccess.get(clazz);
        Object result =  methodAccess.invoke(clazz.newInstance(),"fun01");
    }

转载于:https://my.oschina.net/u/3350266/blog/1928328

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值