Java拾贝第十七天——反射之认识反射相关类

反射相关类

在Java.lang.reflect包下有类:

Constructor:代表一个类中的构造方法
Field:代表一个类中的属性。
Method:代表一个类中的方法。

反射更加的体现Java一切皆对象这个概念

至此,Class类的常用方法如下:

方法 类型 描述
public Constructor<?>[] getConstructors() throws SecurityException 普通方法 获取一个类的全部构造方法
public Field[] getDeclaredFields() throws SecurityException 普通方法 获取一个类声明的全部属性
public Field[] getFields() throws SecurityException 普通方法 获取一个类的全部公开属性
public Method[] getMethods() 普通方法 获取一个类的全部方法
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException 普通方法 根据方法名及参数获取一个方法

还有一个Method类的特殊的方法

 public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,InvocationTargetException


通常来说调用一个方法是:
类实例.对象方法();
类实例.对象方法(传参);


通过反射获取到Method方法后,调用方式如下:
方法对象.invoke(对象实例);
方法对象.invoke(对象实例,传参);

Class.newInstance()创建对象实例

public Constructor<?>[] getConstructors()

获取一个类的全部构造方法

栗子:

package moudle2;

import java.lang.reflect.Constructor;

public class Test17 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("moudle2.Noodle");
            Constructor[] constructors = clazz.getConstructors();

            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Noodle {
    private String name = "面条";
    private double sale=20;

    public Noodle() {
    }
    public Noodle(double sale) {
        this.sale = sale;
    }
    public Noodle(String name, double sale) {
        this.name = name;
        this.sale = sale;
    }
}

程序运行结果:

public moudle2.Noodle()
public moudle2.Noodle(double)
public moudle2.Noodle(java.lang.String,double)

public Field[] getDeclaredFields()

获取一个类声明的属性。(不论访问修饰符等级)

栗子:

package moudle2;

import java.lang.reflect.Field;

public class Test17 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("moudle2.Noodle");
            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                System.out.println(field);
            }

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

class Noodle extends Rice {
    private String name = "面条";
    protected double sale = 20;
    public int i = 10;
}

class Rice {
    private String Rname = "米饭";
    protected double Rsale = 29.9;
    public int Rx = 20;
}

程序运行结果:

private java.lang.String moudle2.Noodle.name
protected double moudle2.Noodle.sale
public int moudle2.Noodle.i

public Field[] getFields()

获取一个类的公开属性(包括继承自父类的公开属性)

栗子:

package moudle2;

import java.lang.reflect.Field;

public class Test17 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("moudle2.Noodle");
            Field[] fields = clazz.getFields();

            for (Field field : fields) {
                System.out.println(field);
            }

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

class Noodle extends Rice {
    private String name = "面条";
    protected double sale = 20;
    public int i = 10;
}

class Rice {
    private String Rname = "米饭";
    protected double Rsale = 29.9;
    public int Rx = 20;
}

程序运行结果:

public int moudle2.Noodle.i
public int moudle2.Rice.Rx

public Method[] getMethods()

获取一个类的全部公开方法(包括继承自父类)

栗子:

package moudle2;

import java.lang.reflect.Method;

public class Test17 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("moudle2.Noodle");
            Method[] methods = clazz.getMethods();

            for (Method method : methods) {
                System.out.println(method);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Noodle extends Rice  {
    public Noodle() {}//构造方法不属于Method类
    private void say(){}
    protected void tell(){}
}

class Rice {
    private void R1(){};
    protected void R2(){};
    public void R3(){};
}

程序运行结果:

public void moudle2.Rice.R3()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

从结果可以发现,不仅打印了Noodle类的方法,还打印了继承自Object类的方法。

public Method getMethod(String name, Class<?>... parameterTypes)

根据方法名获取方法

栗子:

package moudle2;

import java.lang.reflect.Method;

public class Test17 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("moudle2.Noodle");
            Method say = clazz.getMethod("say");
            System.out.println(say);

            Method say1 = clazz.getMethod("say", String.class, double.class);//与方法的传参必须一一对应
            System.out.println(say1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Noodle {
    private String name ;
    private double sale ;

    public Noodle() {
    }
    public void say() {
        System.out.println("无参方法say");
    }
    public void say(String name, double sale) {
        System.out.println("有参方法say" + name + sale);
    }
}

程序运行结果:

public void moudle2.Noodle.say()
public void moudle2.Noodle.say(java.lang.String,double)

public Object invoke(Object obj, Object... args)

使用反射调用方法

栗子:

package moudle2;

import java.lang.reflect.Method;

public class Test17 {
    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("moudle2.Noodle");
            Method say = clazz.getMethod("say");
            say.invoke(clazz.newInstance());

            Method say1 = clazz.getMethod("say", String.class, double.class);
            say1.invoke(clazz.newInstance(),"带参",11);

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

class Noodle {
    private String name ;
    private double sale ;

    public Noodle() {
    }

    public void say() {
        System.out.println("无参方法say");
    }

    public void say(String name, double sale) {
        System.out.println("有参方法say" + name + sale);
    }
}

程序运行结果:

无参方法say
有参方法say带参11.0
posted @ 2023-11-05 21:29  rowbed  阅读(6)  评论(0编辑  收藏  举报