java - 反射 - 方法,构造方法

https://www.cnblogs.com/clamp7724/p/11655237.html

类和属性的反射

 

反射中:

Method描述类中的方法,

Constructor描述类中的构造方法

 

 

package reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodTest {
    public static void main(String[] args){

        try {
            System.out.println("-------------------------------------获取类的方法--------------------------------------------------");
            //通过方法名字, 参数类型的类 (因为方法有重构,名字可能相同)
            Method m1 = TestClass.class.getMethod("methodTest", String.class, int.class);
            Method m2 = TestClass.class.getMethod("methodTest");

            System.out.println(m1.getName());  //返回方法名,getName()的返回值为String类型
            //methodTest
            System.out.println(m1.getReturnType()); //返回返回值的类型     返回值为Class类型
            //int
            System.out.println(m1.getModifiers()); //用数字表示方法的修饰符,相加后返回,int类型返回值
            //1     因为是public
            Class[] cArr_m1 = m1.getParameterTypes(); //返回参数类型的class数组, Class类型返回值
            for(Class c: cArr_m1){
                System.out.println(c.getName());
            }
            //java.lang.String
            //int
            Class[] cArr2_m1 = m1.getExceptionTypes(); //返回抛出异常的类型的数组
            Annotation[] a_m1 = m1.getAnnotations(); //返回注解数组

            System.out.println("-------------------------------------使用类的方法--------------------------------------------------");
            TestClass tc1 = new TestClass();
            //不带参数的构造方法
            int i = (int)m1.invoke(tc1,"name",111);//Method.invoke( 对象,参数1,参数2...参数n );  有返回值的可以正常接收
            //带参数的普通方法
            System.out.println(i);
            //1

            System.out.println("-------------------------------------获取类的私有方法,继承自父类的方法--------------------------------------------------");
            TestClass tc3 = new TestClass();
            //不带参数的构造方法
            Method m3 = TestClass.class.getMethod("toString"); //所有类默认继承Object,toString是Object中的方法
            System.out.println(m3.invoke(tc3));
            //reflect.TestClass@7e0babb1    执行成功,说明取到了父类方法   引用变量的toString是  包名.类名@hashCode

            //Method m4 = TestClass.class.getMethod("privateTest");//会报错,不能取到private
            Method m4 = TestClass.class.getDeclaredMethod("privateTest");  //和取属性的方法类似
            m4.setAccessible(true);//操作私有方法要先给权限,和属性一样
            m4.invoke(tc3);
            //私有的普通方法




        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

 

package reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ConstructorTest {
    public static void main(String[] args) {

        try {
            //基本和普通方法一样。。。
            System.out.println("-------------------------------------获取构造方法的方法--------------------------------------------------");
            //通过参数类型的类 (因为方法有重构,名字可能相同), 构造方法名字和类名一样,所以不用传方法名了
            Constructor c1 = TestClass.class.getConstructor(String.class, int.class);
            Constructor c2 = TestClass.class.getConstructor();

            System.out.println(c1.getName());  //返回类名,getName()的返回值为String类型
            //reflect.TestClass
            System.out.println(c1.getModifiers()); //用数字表示方法的修饰符,相加后返回,int类型返回值
            //1     因为是public
            Class[] cArr_c1 = c1.getParameterTypes(); //返回参数类型的class数组, Class类型返回值
            for (Class c : cArr_c1) {
                System.out.println(c.getName());
            }
            //java.lang.String
            //int

            System.out.println("-------------------------------------构造方法的使用--------------------------------------------------");
            TestClass tc1 = (TestClass)c1.newInstance("name",1);  //构造方法.newInstance(参数1,参数2...参数n);返回一个new的对象
            //带参数的构造方法
            TestClass tc2 = (TestClass)c2.newInstance();
            //不带参数的构造方法

            Constructor c3 = TestClass.class.getDeclaredConstructor(String.class);
            c3.setAccessible(true);
            c3.newInstance("aaa");
            //带参数的私有构造方法  - -感觉...反射这玩意会出很多问题。。。比如单例设计模式用到了private的构造方法保证实例唯一,这下不能保证了。。。





        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

你可能感兴趣的