反射初步

本文深入探讨Java反射机制的核心概念及其实现方式,包括如何通过不同方法获取Class对象、使用反射创建对象实例、获取类的成员变量、构造函数及方法等,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在面向对象的世界里,万物皆对象。类是对象,类是java.lang.Class类的实例对象。另外class类只有java虚拟机才能new出来。任何一个类都是Class。
类的实例对象。这实例对象有三种表达方式:

Class s1=Class.forName("com.lmr.invoke.Student");

Class s2=Student.class;

Student s=new Student();
Class s3=s.getClass();

Class.forName(类的全称);该方法不仅表示了类的类型,还代表了动态加载类。编译时刻加载类是静态加载、运行时刻加载类是动态加载类。

可以利用==运算符实现两个类对象的比较

if(e.getClass()==xx.class){

}

newInstance()可以用来快速创建一个类的实例,前提是该类必须存在一个无参构造方法.

e.getClass.newInstance()

eg1:

private static void initClass() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        // TODO Auto-generated method stub

        //三种实例方式
        Class s1=Class.forName("com.lmr.invoke.Student");

        Class s2=Student.class;

        Student s=new Student(1,"1",1);
        Class s3=s.getClass();

        System.out.println(s1.getName());
        System.out.println(s1.getSimpleName());
        System.out.println(s2.getName());
        System.out.println(s3.getName());

        Student stu1=(Student) s1.newInstance();//通过类的类型创建该类的实例对象 ,前提是该类必须存在一个无参构造方法

        Constructor con=s2.getConstructor(int.class,String.class,int.class);//取得指定参数类型的构造方法
        Student stu2=(Student) con.newInstance(1,"name",12);

        System.out.println(stu1.toString());
        System.out.println(stu2.toString());


    }

结果:

com.lmr.invoke.Student
Student
com.lmr.invoke.Student
com.lmr.invoke.Student
Student [id=0, name=null, age=0]
Student [id=1, name=name, age=12]

通过反射来获取类的结构。
Class类中的getFields()、getMethods()、getConstructors()方法将分别返回类提供的public域、方法和构造器数组,其中包括超类的公有成员。
eg2:

private static void initClassInfo() {
        // TODO Auto-generated method stub

//      Class c=Student.class;
        Class c=Math.class;

        System.out.println(c.getName());
        System.out.println(c.getSimpleName());
//      System.out.println(c.getComponentType());

//      Field[] fields=c.getFields();//获取public类型的成员变量
        Field[] fields=c.getDeclaredFields();//成员变量信息,获取全部

        System.out.println("----------成员变量----------");
        for(Field f:fields){

            int mod=f.getModifiers();
            String modtype=Modifier.toString(mod);//方法的属性

            System.out.println(modtype+" "+f.getType().getSimpleName()+" "+f.getName());

        }

        Constructor[] constructors=c.getDeclaredConstructors();//获取构造函数信息
        System.out.println("----------构造函数----------");
        for(Constructor con:constructors){

            String name=con.getName();//方法名
            Class[] paramterType=con.getParameterTypes();//方法中参数类型

            int mod=con.getModifiers();
            String modtype=Modifier.toString(mod);//方法的属性

            System.out.print(modtype+" "+name+" (");
            for(Class p:paramterType){
                System.out.print(p.getSimpleName()+" ");
            }
            System.out.println(")");

        }

        Method[] methods=c.getMethods();//获取函数方法信息
        System.out.println("-----------方法-----------");
        for(Method m:methods){

            String name=m.getName();//方法名
            Class returnType=m.getReturnType();//方法返回类型
            Class[] paramterType=m.getParameterTypes();//方法中参数类型

            int mod=m.getModifiers();
            String modtype=Modifier.toString(mod);//方法的属性

            System.out.print(modtype+" "+returnType.getSimpleName()+" "+name+" (");
            for(Class p:paramterType){
                System.out.print(p.getSimpleName()+" ");
            }
            System.out.println(")");
        }

    }

结果:

java.lang.Math
Math
----------成员变量----------
public static final double E
public static final double PI
private static long negativeZeroFloatBits
private static long negativeZeroDoubleBits
static double twoToTheDoubleScaleUp
static double twoToTheDoubleScaleDown
static final boolean $assertionsDisabled
----------构造函数----------
private java.lang.Math ()
-----------方法-----------
public static int abs (int )
public static double abs (double )
public static float abs (float )
public static long abs (long )
public static double sin (double )
public static double cos (double )
public static double tan (double )
public static double atan2 (double double )
public static double sqrt (double )
public static double log (double )
public static double log10 (double )
public static double pow (double double )
public static double exp (double )
public static long min (long long )
public static double min (double double )
public static float min (float float )
public static int min (int int )
public static double max (double double )
public static float max (float float )
public static long max (long long )
public static int max (int int )
public static long addExact (long long )
public static int addExact (int int )
public static int decrementExact (int )
public static long decrementExact (long )
public static long incrementExact (long )
public static int incrementExact (int )
public static long multiplyExact (long long )
public static int multiplyExact (int int )
public static int negateExact (int )
public static long negateExact (long )
public static int subtractExact (int int )
public static long subtractExact (long long )
public static double scalb (double int )
public static float scalb (float int )
public static double copySign (double double )
public static float copySign (float float )
public static int getExponent (float )
public static int getExponent (double )
public static double signum (double )
public static float signum (float )
public static double IEEEremainder (double double )
public static double acos (double )
public static double asin (double )
public static double atan (double )
public static double cbrt (double )
public static double ceil (double )
public static double cosh (double )
public static double expm1 (double )
public static double floor (double )
public static long floorDiv (long long )
public static int floorDiv (int int )
public static int floorMod (int int )
public static long floorMod (long long )
public static double hypot (double double )
public static double log1p (double )
public static float nextAfter (float double )
public static double nextAfter (double double )
public static double nextDown (double )
public static float nextDown (float )
public static double nextUp (double )
public static float nextUp (float )
public static double random ()
public static double rint (double )
public static int round (float )
public static long round (double )
public static double sinh (double )
public static double tanh (double )
public static double toDegrees (double )
public static int toIntExact (long )
public static double toRadians (double )
public static double ulp (double )
public static float ulp (float )
public final void wait ()
public final void wait (long int )
public final native void wait (long )
public boolean equals (Object )
public String toString ()
public native int hashCode ()
public final native Class getClass ()
public final native void notify ()
public final native void notifyAll ()

获取一个方法:需要获取方法的名称和方法的参数才能决定一个方法。

Class[] paramtype={int.class, int.class};
Method m=calculateclass.getMethod("add", paramtype);

Method m=calculateclass.getMethod("add", int.class, int.class);

方法的反射操作:method.invoke(对象,参数列表);

eg1:

public static void InvokeOne(){

    try {
        Class calculateclass=Class.forName("com.lmr.invoke.Calculate");

        Class[] paramtype={int.class, int.class};
        Method m=calculateclass.getMethod("add", paramtype);

//          Method m=calculateclass.getMethod("add", int.class, int.class);

        m.invoke(calculateclass.newInstance(), 1, 2);//method.invoke(对象,参数列表);

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public class Calculate {

    public void add(int a,int b){
        System.out.println(a+b);
    }

    public void subtract(int a,int b){
        System.out.println(a-b);
    }

    public void multiply(int a,int b){
        System.out.println(a*b);
    }

    public void divide(int a,int b){
        if(b!=0){
            System.out.println(a/b);
        }
    }

}

结果:打印出1+2的结果,3

Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;
class-类对象
Constructor-类的构造器对象
Field-类的属性对象
Method-类的方法对象

反射的操作都是在运行时进行的

private static void InvokeTwo() {
        // TODO Auto-generated method stub

    try {

        Class studentclass=Class.forName("com.lmr.invoke.Student");

        Object stuobj=studentclass.newInstance();

        Method setStuName=studentclass.getMethod("setName", String.class);
        setStuName.invoke(stuobj, "Jack");

//          PropertyDescriptor pd=new PropertyDescriptor("name", studentclass);//通过属性名来获取对应的存储器,从而获取其get,set方法
//          Method setStuName=pd.getWriteMethod();

        Method toStuString=studentclass.getMethod("toString");
        System.out.println(toStuString.invoke(stuobj));

        Field name=studentclass.getDeclaredField("name");
        name.setAccessible(true);//由于name是一个私有域,所有须解除封装
        name.set(stuobj, "Jane");

        System.out.println(toStuString.invoke(stuobj));

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

结果:

Student [id=0, name=Jack, age=0]
Student [id=0, name=Jane, age=0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值