java反射的简单介绍

反射

​ 反射库(reflection library)提供了一个非常丰富且精心设计的工具集,以便编写能够动态操纵java代码的程序。大量的框架中都用到了反射技术,我所接触过的反射技术一般都与接口结合使用,具体怎么实现,下面详细讲解。

有关于本文提到的类库的方法信息,请详见java api 文档;

1 java.lang.Class 类

java运行时系统始终为所有对象维护一个被称为运行时的类型标识。这个信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。

我们可以根据一个实例找到他所属的对应的类信息。

package reflect;

public class Employee {

    public static void main(String[] args) {
        Employee e = new Employee();
        Class cl = e.getClass();
        System.out.println(cl.getName());
    }
}

输出结果:

reflect.Employee

我们可以看到,输出结果为该实例 e 所对应的类信息的全路径名称(包括包名)。

利用反射实现利用类的全路径名称得到一个该类的实例。

package reflect;

public class Employee {

public static int count = 0;

public Employee() {
    count++;
}

public static int getCount() {
    return count;
}

public static void main(String[] args) throws InstantiationException,
        IllegalAccessException, ClassNotFoundException {
    Employee e = new Employee();
    System.out.println(e.getCount());
    Employee e1 = (Employee) Class.forName("reflect.Employee").newInstance();
    System.out.println(e1.getCount());
}

}

输出结果:

1
2

通过上述的例子,我们可以看出,我们建立了两个实例,一个是通过正常的方式,一个是通过反射的方式,而在实际开发中,在反射的强制类型转化时,我们一般将其转化为接口类型,然后使得Employee实现该接口,根据java的动态加载特点,就可以大大的提高代码的灵活性。newInstance()方法其实就是Employee类的无参构造方法。

2 java.lang.reflect.Field 类

java是一种面向对象的语言,一切皆为对象,通过Class信息,我们可以得到这个类的所有字段信息。

package reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Employee {

    public static int count = 0;

    public String name = "tjy";

    public int age = 26;

    private double sar = 20.00;

    public static void main(String[] args) throws InstantiationException,
            IllegalAccessException, ClassNotFoundException {
        Class cl = Class.forName("reflect.Employee");
        //获得类的所有字段
        Field[] fields = cl.getDeclaredFields();

        for(Field f : fields){
            //得到字段类型
            Class type = f.getType();
            //得到字段名字
            String name = f.getName();
            //获取字段的域
            String modifiers = Modifier.toString(f.getModifiers());
            if(modifiers.length() >0){
                System.out.print(modifiers + "  ");
            }
            System.out.println(type.getName()+": "+name+";");
        }
    }
}

输出结果:

扫描二维码关注公众号,回复: 1190755 查看本文章
public static  int: count;
public  java.lang.String: name;
public  int: age;
private  double: sar;

3 java.lang.reflect.Method 类

package reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Employee {

    public static String name = "tjy";

    public void sayHello(){
        System.out.println("Hello");
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public static void main(String[] args) throws InstantiationException,
            IllegalAccessException, ClassNotFoundException {
        Class cl = Class.forName("reflect.Employee");
        //获得类的所有方法
        Method[] methods = cl.getDeclaredMethods();
        for(Method method:methods){
            //获取方法返回值类型
            Class type = method.getReturnType();
            //获取方法名称
            String name = method.getName();
            //获取方法域
            String modifiers = Modifier.toString(method.getModifiers());
            if(modifiers.length() > 0){
                System.out.print(modifiers+"  ");
            }
            System.out.println(type.getName()+": "+name+";");
        }

    }
}

输出结果:

public  void: sayHello;
public  java.lang.String: getName;
public  void: setName;
public static  void: main;

此示例展示利用类得到该类的方法信息。下面介绍怎么通过得到的方法信息来调用方法。

package reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Employee {

    public static String name = "tjy";

    public void sayHello(){
        System.out.println("Hello");
    }

    public static void sayName(){
        System.out.println("Welecome! "+name);
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public static void main(String[] args) throws Exception {

        //获得类信息
        Class cl = Class.forName("reflect.Employee");
        //获得“sayHello"方法
        Method m1 = cl.getMethod("sayHello", null);
        //调用sayHello方法
        m1.invoke(cl.newInstance(), null);

        //获得“sayName”方法
        Method m2 = cl.getMethod("sayName", null);
        //调用sayName方法,static 方法不用传递实例
        m2.invoke(null, null);

        //获得“getName”方法
        Method m3 = cl.getMethod("getName", null);
        //调用“getName”方法
        String name = (String)m3.invoke(cl.newInstance(), null);
        System.out.println(name);

        //获得“setName”方法,后一个参数为参数的类信息
        Method m4 = cl.getMethod("setName", String.class);
        m4.invoke(cl.newInstance(), "tjy_521");
        //调用“getName”方法
        name = (String)m3.invoke(cl.newInstance(), null);
        System.out.println(name);
    }
}

输出结果:

Hello
Welecome! tjy
tjy
tjy_521

反射工具类库还有很多其他的类,由于一个类,我们最关心的还是它的属性及行为,所以,在这里,我就只介绍了Class、Field、Method这几个简单的类及常用的方法,请各位具体用到的时候在深入了解。

猜你喜欢

转载自blog.csdn.net/tjy_521/article/details/80279594