Java反射(1)-通过反射获取使用Class对象、方法、属性

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。

反射非常强大,JDBC以及主流的框架如Spring、Mybatis等等都使用到了反射机制,可以说只要使用Java,反射无处不在。本文详细介绍如何使用反射获取到Class对象,类的方法和属性。

1.Class对象

Class对象包括一个类的方法、变量、接口、类名、类修饰符等等信息,获取Class对象有三种方法。

  1. 对象.getClass方法
  2. 类名.class属性
  3. Class的forName方法,参数为类的全路径
		//获取Class对象的三种方法
        Test test = new Test();
        Class c1 = test.getClass();
        Class c2=Test.class;
        Class c3=Class.forName("ClassTest.Test");

2.获取类的各种信息

获取类名

 //获取类名
    String name=c1.getName();
    String simplename=c1.getSimpleName();
    System.out.println("类名(带包名称):"+name);
    System.out.println("类名(不带包名称):"+simplename);

获取类修饰符

  //获取类修饰符
    int modifierid=c1.getModifiers();
    //通过返回int值判断是否是某一修饰符
    boolean isPublic=Modifier.isPublic(modifierid);
    boolean isPrivate=Modifier.isPrivate(modifierid);
    boolean isAbstract=Modifier.isAbstract(modifierid);
    boolean isFinal=Modifier.isFinal(modifierid);
    boolean isInterface=Modifier.isInterface(modifierid);

    System.out.println(modifierid+"是否public:"+isPublic);
    System.out.println(modifierid+"是否Private:"+isPrivate);
    System.out.println(modifierid+"是否Abstract:"+isAbstract);
    System.out.println(modifierid+"是否Final:"+isFinal);
    System.out.println(modifierid+"是否Interface:"+isInterface);

获取包信息

	//获取包信息
    Package pack=c1.getPackage();
    System.out.println("包信息:"+pack.getName());

获取父类的Class对象

	//获取父类的Class对象
	Class parentclass=c1.getSuperclass();
	System.out.println("父类对象:"+parentclass.getName());

获取接口信息

	//获取接口信息
    Class [] interfacename=c1.getInterfaces();
    for (Class c:interfacename)
            System.out.println("实现接口:"+c.getName());

获取构造函数Constructor

		//获取构造函数Constructor
        Constructor [] constructors=c1.getConstructors();
        for (Constructor constructor:constructors){
            System.out.print("构造方法名称:"+constructor.getName());
            Class[] parameterTypes = constructor.getParameterTypes();
            for (Class parameterType:parameterTypes){
                System.out.print("\t构造方法参数:"+parameterType.getName());
            }
            System.out.println();
        }

3.生成实例对象

		//生成对象
        Constructor con=c1.getConstructor(int.class,String.class);
        Test instance= (Test) con.newInstance(18,"张三");
        instance.Print();
        System.out.println();

4.获取成员方法并调用

		//获取成员方法
        Method[] methods=c1.getDeclaredMethods();
        System.out.print("Test的方法有:");
        for (Method method1:methods){
            System.out.print(method1.getName()+"     ");
        }
        System.out.println();
        Method method=c1.getDeclaredMethod("Hello", String.class);
        System.out.println("获取到的Hello方法名字:"+method.getName());

 		//获取成员方法参数
        Class[] parameterTypes = method.getParameterTypes();
        System.out.print("参数列表:");
        for (Class parameterType : parameterTypes){
            System.out.println(parameterType.getTypeName());
        }
        //获取成员方法返回类型
        Class  returnType=method.getReturnType();
        System.out.println("返回类型:"+returnType.getTypeName());
        //调用成员方法
        //调用私有方法需要调用setAccessible方法设置为true
        method.setAccessible(true);
        method.invoke(con.newInstance(18,"张三"),"李四");
        System.out.println();

5.获取成员属性,取值和赋值

		//获取成员变量,通过get,set方法获属性取值和赋值
 		Field[] fields = c1.getFields();
        Field[] fields1=c1.getDeclaredFields();
        Field field=c1.getField("age");
        System.out.print("getFields:");
        for (Field f:fields){
            System.out.print(f.getName()+":"+f.get(instance)+"  ");
        }
        System.out.println();
        System.out.print("getDeclaredFields:");
        for (Field f:fields1){
            //调用私有属性需要调用setAccessible方法设置为true
            f.setAccessible(true);
            System.out.print(f.getName()+":"+f.get(instance)+"  ");
        }
        System.out.println();
        field.set(instance,20);
        System.out.println("getField:"+field.getName()+":"+field.get(instance));

6.总结

上面的代码有点需要注意:
1.必须调用setAccessible(true)方法,这是针对私有变量而言,public和protected等都不需要。这个方法是允许通过反射访问类的私有变量或者私有方法。
2.getDeclaredFields为获取所有属性,getFields不能获取到私有属性。获取方法部分同理。
私有变量和私有方法也是不允许其他的类随意调用的,但是通过反射可以饶过这一限制。
反射功能非常强大,可以在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法。

7.运行截图

在这里插入图片描述

在这里插入图片描述

8.所有演示代码

Main类


import java.lang.reflect.*;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获取Class对象的三种方法
        Test test = new Test();
        Class c1 = test.getClass();
        Class c2=Test.class;
        Class c3=Class.forName("ClassTest.Test");


        //获取类名
        String name=c1.getName();
        String simplename=c1.getSimpleName();
        System.out.println("类名(带包名称):"+name);
        System.out.println("类名(不带包名称):"+simplename);
        System.out.println();

        //获取类修饰符
        int modifierid=c1.getModifiers();
        boolean isPublic=Modifier.isPublic(modifierid);
        boolean isPrivate=Modifier.isPrivate(modifierid);
        boolean isAbstract=Modifier.isAbstract(modifierid);
        boolean isFinal=Modifier.isFinal(modifierid);
        boolean isInterface=Modifier.isInterface(modifierid);
        System.out.println(modifierid+"是否public:"+isPublic);
        System.out.println(modifierid+"是否Private:"+isPrivate);
        System.out.println(modifierid+"是否Abstract:"+isAbstract);
        System.out.println(modifierid+"是否Final:"+isFinal);
        System.out.println(modifierid+"是否Interface:"+isInterface);
        System.out.println();

        //获取包信息
        Package pack=c1.getPackage();
        System.out.println("包信息:"+pack.getName());
        System.out.println();

        //获取父类的Class对象
        Class parentclass=c1.getSuperclass();
        System.out.println("父类对象:"+parentclass.getName());
        System.out.println();

        //获取接口信息
        Class [] interfacename=c1.getInterfaces();
        for (Class c:interfacename)
            System.out.println("实现接口:"+c.getName());
        System.out.println();

        //获取构造函数Constructor
        Constructor [] constructors=c1.getConstructors();
        for (Constructor constructor:constructors){
            System.out.print("构造方法名称:"+constructor.getName());
            Class[] parameterTypes = constructor.getParameterTypes();
            for (Class parameterType:parameterTypes){
                System.out.print("\t构造方法参数:"+parameterType.getName());
            }
            System.out.println();
        }
        System.out.println();

        //生成对象
        Constructor con=c1.getConstructor(int.class,String.class);
        Test instance= (Test) con.newInstance(18,"张三");
        instance.Print();
        System.out.println();

        //获取成员方法
        Method[] methods=c1.getDeclaredMethods();
        System.out.print("Test的方法有:");
        for (Method method1:methods){
            System.out.print(method1.getName()+"     ");
        }
        System.out.println();
        Method method=c1.getDeclaredMethod("Hello", String.class);
        System.out.println("获取到的Hello方法名字:"+method.getName());
        //获取成员方法参数
        Class[] parameterTypes = method.getParameterTypes();
        System.out.print("参数列表:");
        for (Class parameterType : parameterTypes){
            System.out.println(parameterType.getTypeName());
        }
        //获取成员方法返回类型
        Class  returnType=method.getReturnType();
        System.out.println("返回类型:"+returnType.getTypeName());
        //调用成员方法
        method.setAccessible(true);
        method.invoke(con.newInstance(18,"张三"),"李四");
        System.out.println();

        //获取成员变量,通过get,set方法获属性取值和赋值
        Field[] fields = c1.getFields();
        Field[] fields1=c1.getDeclaredFields();
        Field field=c1.getField("age");
        System.out.print("getFields:");
        for (Field f:fields){
            System.out.print(f.getName()+":"+f.get(instance)+"  ");
        }
        System.out.println();
        System.out.print("getDeclaredFields:");
        for (Field f:fields1){
            f.setAccessible(true);
            System.out.print(f.getName()+":"+f.get(instance)+"  ");
        }
        System.out.println();
        field.set(instance,20);
        System.out.println("getField:"+field.getName()+":"+field.get(instance));

    }
}

Test类

package ClassTest;


public class Test  implements interfacetest  {
    public int age=0;
    private String name="默认名字";

    public  Test(){
        System.out.println("空构造函数调用了");
    }
    public Test(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String Print(){
        System.out.println("名字:"+name+" 年龄:"+age);
        return name+age;
    }

    private void Hello(String who){
        System.out.println("Hello "+who+",这是我的私有方法hello");
    }


}

接口interfacetest

package ClassTest;

public interface interfacetest {
}

版权声明:本文为weixin_44259244原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。