小透明的java学习记录(1)——反射机制

简单的介绍

利用java的反射机制,我们可以得到java代码中任意一个类所拥有的属性和方法,可以调用任意一个对象所拥有的的属性和方法。

获取Class对象

三种方式

  1. 类名.class 需明确到类中的静态成员,相对简单
  2. 对象.getclass() 需创建具体的对象,比较麻烦
  3. Class.getName(具体类名) 只需一个类名,更为方便
public class FansheStudy {

    public static void main(String[] args) throws ClassNotFoundException{
        //类名.class   需明确到类中的静态成员,相对简单
        Class c1 = FansheStudy.class;
        System.out.println(c1.getName());
        
        //对象.getclass()  需创建具体的对象,比较麻烦
        Class c2 = new FansheStudy().getClass();
        System.out.println(c2.getName());
        
        //Class.getName(具体类名)  只需一个类名,更为方便
        Class c3 = Class.forName("com.study.reflection.FansheStudy");
        System.out.println(c3.getName());

        System.out.println("三种方法得到的类对象" + ((c1 == c2 && c1 == c3) ? "是": "不是") + "相等的");
    }
}

三种方法得到的类对象是相等的

com.study.reflection.FansheStudy
com.study.reflection.FansheStudy
com.study.reflection.FansheStudy
三种方法得到的类对象是相等的

获取属性

根据不同的需求有4种获取形式

  1. getFields() 获取该类及其父类所有public属性
  2. getDeclaredFields() 获取该类所有属性
  3. getField(String name) 获取该类及其父类指定public属性
  4. getDeclaredField(String s) 获取该类指定属性
public class FatherClass {
    public String FatherClass_s;
    private int FatherClass_i;
}

public class FansheStudy extends FatherClass {

    public int FansheStudy_a;
    public String FansheStudy_b;
    private int FansheStudy_c = 0;
    public static String FansheStudy_d = "FansheStudy类的静态属性值";

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException{
        Class c = Class.forName("com.study.reflection.FansheStudy");

        //getFields()  获取该类及其父类所有public属性
        Field[] fs = c.getFields();
        System.out.print("获取该类及其父类所有的public属性 : ");
        for(Field ff : fs){
            System.out.print(ff.getName() + " ");
        }
        System.out.println();

        //getDeclaredFields()  获取该类所有属性
        Field[] fds = c.getDeclaredFields();
        System.out.print("获取该类所有属性 : " );
        for(Field ff : fds){
            ff.setAccessible(true);//使private属性值可见
            System.out.print(ff.getName() + " ");
        }
        System.out.println();

        //getField(String name) 获取该类及其父类指定public属性
        Field f = c.getField("FatherClass_s");
        System.out.println("获取指定属性 : " + f.getName());

        Field f_1 = c.getSuperclass().getDeclaredField("FatherClass_i");
        f_1.setAccessible(true);
        System.out.println("获取父类指定的私有属性 : " + f_1.getName());

        //getDeclaredField(String s)  获取该类指定属性
        Field fd = c.getDeclaredField("FansheStudy_d");
        System.out.println("获取该类指定属性 : " + fd.getName() + ", 他的值为 : " + fd.get(FansheStudy.class));//该属性是静态的,所以可用FansheStudy.class,否则应创建具体的对象

        Field fd_1 = c.getDeclaredField("FansheStudy_c");
        FansheStudy fss = new FansheStudy();
        fd_1.set(fss, 5);//
        System.out.println("设置的" + fd_1.getName() + "的值为 : " + fd_1.get(fss));
    }
}

运行代码输出的结果是

获取该类及其父类所有的public属性 : FansheStudy_a FansheStudy_b FansheStudy_d FatherClass_s 
获取该类所有属性 : FansheStudy_a FansheStudy_b FansheStudy_c FansheStudy_d 
获取指定属性 : FatherClass_s
获取父类指定的私有属性 : FatherClass_i
获取该类指定属性 : FansheStudy_d, 他的值为 : FansheStudy类的静态属性值
设置的FansheStudy_c的值为 : 5

获取构造函数

  1. getConstructors() 获取该类所有public构造函数
  2. getDeclaredConstructors() 获取该类所有构造函数
  3. getConstructor(Class… parameterTypes) 获取有指定参数的构造函数
  4. Constructor类中的newInstance(Object… initargs)方法 使用构造函数创建新的对象
public class FansheStudy {
    int i;
    String s;

    public FansheStudy(){};

    public FansheStudy(String s){}

    public FansheStudy(int i, String s){
        this.i = i;
        this.s = s;
    }

    private FansheStudy(int i){}

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException  {
        Class c = Class.forName("com.study.reflection.FansheStudy");

        //getConstructors()   获取该类所有public构造函数
        System.out.println("获取该类所有public构造函数 : ");
        Constructor[] con = c.getConstructors();
        for(Constructor cc : con){
            System.out.println(cc);
        }
        System.out.println();

        //getDeclaredConstructors()   获取该类所有构造函数
        System.out.println("获取该类所有构造函数 : ");
        Constructor[] cond = c.getDeclaredConstructors();
        for(Constructor cc : cond){
            System.out.println(cc);
        }
        System.out.println();

        //getConstructor(Class... parameterTypes)   获取有指定参数的构造函数
        System.out.println("获取有指定参数的构造函数 : ");
        System.out.println(c.getConstructor(int.class, String.class));
        System.out.println();

        //使用构造函数创建新的对象
        System.out.println("使用构造函数创建新的对象 : ");
        FansheStudy fansheStudy = (FansheStudy) c.getConstructor(int.class, String.class).newInstance(1, null);
        System.out.println("赋予的对象的值为 : " + fansheStudy.i + fansheStudy.s);
    }
}

运行代码输出的结果是

获取该类所有public构造函数 : 
public com.study.reflection.FansheStudy(int,java.lang.String)
public com.study.reflection.FansheStudy(java.lang.String)
public com.study.reflection.FansheStudy()

获取该类所有构造函数 : 
private com.study.reflection.FansheStudy(int)
public com.study.reflection.FansheStudy(int,java.lang.String)
public com.study.reflection.FansheStudy(java.lang.String)
public com.study.reflection.FansheStudy()

获取有指定参数的构造函数 : 
public com.study.reflection.FansheStudy(int,java.lang.String)

使用构造函数创建新的对象 : 
赋予的对象的值为 : 1null

获取方法

  1. getMethods() 获取该类及其父类所有public的方法
  2. getDeclaredMethods() 获取该类所有的方法
  3. getDeclaredMethod(String name, Class… parameterTypes) 获取该类指定的方法
  4. getMethod(String name, Class… parameterTypes) 获取该类及其父类指定的public方法
  5. Method. invoke(Object var1, Object… var2) 执行指定方法
public class FansheStudy {
    int i;
    String s;

    public void test(){};

    public String test(String s){
        this.s = s;
        System.out.println("执行了该类的test方法");
        return s;
    }

    public FansheStudy(int i, String s){
        this.i = i;
        this.s = s;
    }

    private int test(int i){
        this.i = i;
        return i;
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Class c = Class.forName("com.study.reflection.FansheStudy");
        //getMethods(),获取该类及其父类所有public的方法
        Method[] m = c.getMethods();
        System.out.println("getMethods()  获取该类及其父类所有public的方法");
        for(Method mm : m){
            System.out.print(Modifier.toString(mm.getModifiers()) + " ");
            System.out.print(mm.getReturnType().getSimpleName() + " ");
            System.out.print(mm.getName() + " (");
            Class[] p = mm.getParameterTypes();
            for(int i = 0; i < p.length; i++){
                System.out.print(p[i].getSimpleName() + " arg" + i);
                if(i != p.length -1){
                    System.out.print(", ");
                }
            }
            System.out.print(")");

            Class[] e = mm.getExceptionTypes();
            if(e.length > 0){
                System.out.print(" throws ");
                for(int i = 0; i < e.length; i++){
                    System.out.print(e[i].getSimpleName());
                    if(i != e.length -1){
                        System.out.print(", ");
                    }
                }
            }
            System.out.println("{}");
        }
        System.out.println();

        //getDeclaredMethods(),获取该类所有的方法
        Method[] md = c.getDeclaredMethods();
        System.out.println("getDeclaredMethods()  获取该类所有的方法 : ");
        for(Method mm : md){
            mm.setAccessible(true);
            System.out.print(Modifier.toString(mm.getModifiers()) + " ");
            System.out.print(mm.getReturnType().getSimpleName() + " ");
            System.out.print(mm.getName() + " (");
            Class[] p = mm.getParameterTypes();
            for(int i = 0; i < p.length; i++){
                System.out.print(p[i].getSimpleName() + " arg" + i);
                if(i != p.length -1){
                    System.out.print(", ");
                }
            }
            System.out.print(")");

            Class[] e = mm.getExceptionTypes();
            if(e.length > 0){
                System.out.print(" throws ");
                for(int i = 0; i < e.length; i++){
                    System.out.print(e[i].getSimpleName());
                    if(i != e.length -1){
                        System.out.print(", ");
                    }
                }
            }
            System.out.println("{}");
        }
        System.out.println();

        //getDeclaredMethod(String name, Class... parameterTypes),获取该类指定的方法
        Method mmm = c.getDeclaredMethod("test", String.class);
        System.out.println("getDeclaredMethods(),获取该类指定的方法 : " + mmm.getName());
        FansheStudy ff = new FansheStudy(1, null);
        mmm.invoke(ff, "hello");
    }
}

运行程序输出结果

getMethods()  获取该类及其父类所有public的方法
public static void main (String[] arg0) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{}
public String test (String arg0){}
public void test (){}
public final void wait (long arg0, int arg1) throws InterruptedException{}
public final native void wait (long arg0) throws InterruptedException{}
public final void wait () throws InterruptedException{}
public boolean equals (Object arg0){}
public String toString (){}
public native int hashCode (){}
public final native Class getClass (){}
public final native void notify (){}
public final native void notifyAll (){}

getDeclaredMethods()  获取该类所有的方法 : 
public static void main (String[] arg0) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{}
public String test (String arg0){}
private int test (int arg0){}
public void test (){}

getDeclaredMethods(),获取该类指定的方法 : test
执行了test方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值