java反射技术

一、基本反射技术

1.1

getClass():根据一个对象获得它的类

public class Test4 {

    public static void main(String[] args)  {

        Role r1=new Role();
        Class<? extends Role> c1=r1.getClass();
        
        System.out.println(c1);//打印:class euler1.Role
        System.out.println(c1.getName());//euler1.Role
        System.out.println(c1.getSimpleName());//Role
        System.out.println(c1.getTypeName());//euler1.Role
        System.out.println(Arrays.toString(c1.getConstructors()));//[public euler1.Role()]
    }

}

Class.forName():根据类的全限定名获得它的类

public class Test4 {

    public static void main(String[] args)  {

        String s1="euler1.Role";//只能打全限定名
        Class<?> c2=null;
        try {
            c2 = Class.forName(s1);
            System.out.println(c2);//class euler1.Role
            System.out.println(c2.getSimpleName());//Role
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

Type属性:

基本类型都有type属性,可以得到这个基本类型的类型,比如

Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Float.TYPE;
Class c4 = Double.TYPE;
System.out.println(c1);//bolean

二、获取类的成员

当类中方法定义为私有的时候我们能调用?不能!当变量是私有的时候我们能获取吗?不能!但是反射可以,比如源码中有你需要用到的方法,但是那个方法是私有的,这个时候你就可以通过反射去执行这个私有方法,并且获取私有变量。

获取类的构造函数

获取类的所有构造方法

public static void main(String[] args)  {
        Test test = new Test();
         Class<? extends Test> c4 = test.getClass();
         Constructor[] constructors ;
         Constructor[] constructors1 ;
         constructors = c4.getDeclaredConstructors();//getDeclaredConstructors()返回类的所有构造方法
         constructors1 = c4.getConstructors();//getConstructors()返回类的所有public构造方法
         System.out.println(Arrays.toString(constructors));
         System.out.println(Arrays.toString(constructors1));
         for(int i=0;i<constructors.length;i++) {
             //getModifiers可以得到构造方法的类型:private,public等等
             System.out.print(Modifier.toString(constructors[i].getModifiers()) + "参数:");
             //getParameterTypes可以得到构造方法的所有参数的类型,返回的是一个Class数组:比如返回int,String类型等等
             Class[] parametertypes = constructors[i].getParameterTypes();
             
             for(int j=0;j<parametertypes.length;j++) {
                 System.out.print(parametertypes[j].getName() + " ");
             }
             System.out.println("");
         }
            
    }

获取类中特定的构造方法

1)获取无参构造方法

public class Test5 {

    public static void main(String[] args)  {
        Test test = new Test();
         Class<? extends Test> c4 = test.getClass();
         Constructor constructors ;
         try {
             //获取无参构造方法直接不传参数
            constructors = c4.getDeclaredConstructor();//少个s就是返回的是一个Class对象而不是一个Class数组
            System.out.print(Modifier.toString(constructors.getModifiers()));
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

2)获取类中特定的构造方法

public static void main(String[] args)  {
        Test test = new Test();
         Class<? extends Test> c4 = test.getClass();
         Class[] p={int.class,String.class};
         Constructor constructors ;
         try {
             //获取特定构造方法,传一个指示参数个数及类型的class对象或数组
            constructors = c4.getDeclaredConstructor(p);//少个s就是返回的是一个Class对象而不是一个Class数组
            System.out.print(Modifier.toString(constructors.getModifiers())+" ");
            Class[] parametertypes = constructors.getParameterTypes();
            for (int j = 0; j < parametertypes.length; j++) {
                System.out.print(parametertypes[j].getName() + " ");
            }
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }

调用public构造方法

Class[] p = {int.class,String.class};
 constructors = c4.getDeclaredConstructor(p);
//传递参数进去
 constructors.newInstance(24,"HuangLinqing");

调用私有构造方法

Class[] p = {String.class};   constructors = c4.getDeclaredConstructor(p);   constructors.setAccessible(true);   constructors.newInstance("HuangLinqing");

调用类的私有方法

我们知道如果我们要正常的调用类的方法都是通过类.方法调用,所以我们调用私有方法也需要得到类的实例,而我们上面newInstace已经得到了类的实例,这样就好办了。

Class[] p4 = {String.class};
//首先通过 getDeclaredMethod方法获取到这个私有方法,第一个参数是方法名,第二个参数是参数类型      Method method = c4.getDeclaredMethod("welcome",p4);      method.setAccessible(true);
// 然后通过invoke方法执行,invoke需要两个参数一个是类的实例,一个是方法参数      Object arg1s[] = {"欢迎关注代码男人技术公众号"};      method.invoke(test,arg1s);

获取类的私有字段并修改值

看到这里你可能会说,有了set方法,什么私有不私有,test.set不就可以了,但是这里要注意我们是没有办法得到这个类的实例的,要不然都可以得到实例就没有反射一说了。我们在通过反射得到类的实例之后先获取字段:

Test test1=null;
         
            try {
                test1=(Test)Class.forName("euler1.Test").newInstance();
                try {
                    //先获取字段
                    Field field=c4.getDeclaredField("name");
                    field.setAccessible(true);
                    //通过对象实例设置值
                    field.set(test1,"代码男人");
  //获取值
                    System.out.println(field.get(test1).toString());
                } catch (NoSuchFieldException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (SecurityException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

获取类的所有方法

构造方法,set,get方法,继承来的方法等等所有的方法

public class Test5 {

    public static void main(String[] args)  {
        try {
            Class c1=Class.forName("euler1.Test");
            //获取这个类的所有方法
            Method[] methods = c1.getMethods();
            System.out.println(Arrays.toString(methods));
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

--

原文地址:https://www.cnblogs.com/xc-xinxue/p/12492173.html