反射小结

       什么是反射?书上是这样定义的:“在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制”

      要想了解反射,必须了解这四种API:

Class类:反射的核心类,可以获取类的Constructor,Method和Field属性。(注意:不要和class关键字搞混)

Constructor类:Java.lang.reflec包中的类,表示类中的构造方法。

Method类:Java.lang.reflec包中的类,表示类中的成员方法。

Field类:Java.lang.reflec包中的类,表示类中的成员变量。

        下面我将根据API从四个方面讲一下反射的基本应用,先定义一个父子类:

package com.Jevin.blog;

public class Person {

    /**
     * 成员变量:
     */
    public String name;
    protected int age;
    String id;
    private String weight;



    /**
     * 成员方法:
     */
    public void love(){
        System.out.println("每个人都有追求爱的权利!");
    }

    protected void makeLove(){
        System.out.println("所以我们都喜欢做爱!");
    }

    void romatic(){
        System.out.println("爱情除了做,还需要浪漫!");
    }

    private void life(){
        System.out.println("我们同样都需要生活!");
    }
}
package com.Jevin.blog;

public class Student extends Person {

    /**
     * 成员变量:
     */
    public String stuNo;
    protected String className;
    int score;
    private String hobby;

    /**
     * 构造方法:
     */
    public Student(){
        System.out.println("共有的无参构造方法!");
    }
    public Student(String stuNo){
        System.out.println("共有的带参数的构造方法stuNo="+stuNo);
    }
    protected Student(int score){
        System.out.println("受保护的有参构造方法score="+score);
    }
    Student(String hobby,int score){
        System.out.println("默认的有参构造方法hobby="+hobby+",score="+score);
    }
    private Student(String stuNo,String className,int score){
        System.out.println("私有的构造方法:stuNo="+stuNo+",className="+className+",score="+score);
    }


    /**
     * 成员方法:
     */
    public void test(int a,boolean b){
        System.out.println("作为学生,我们都需要考试!");
    }
    void getScore(String str){
        System.out.println("还需要拿高分数!");
    }
    protected void hateScore(double d){
        System.out.println("但是我们都讨厌分数!");
    }
    private void CEE(String eng){
        System.out.println("但是不得不面对高考!");
    }
}

一:创建反射的三种方式:

package com.Jevin.blog;

/**
 * 创建反射类型的三种方式:
 */
public class ReflectType {
    public static void main(String[] args) throws Exception {

        //方式一:".class"
        Class clazz1=Student.class;

        //方式二:"Class.forName(String args)"
        Class clazz2=Class.forName("com.Jevin.blog.Student");

        //方式三:"引用.getClass()"
        Student student=new Student();
        Class clazz3=student.getClass();
    }
}

二:利用反射获取类中的构造方法:

package com.Jevin.blog;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

/**
 * 利用反射获取类中的构造方法:
 */
public class ConstructorTest {
    public static void main(String[] args) throws Exception {

        Class clazz=Class.forName("com.Jevin.blog.Student");

        //1.通过"getConstructors()"获取当前类所有的public的构造方法:
        /*Constructor[] constructors1=clazz.getConstructors();
        for(Constructor constructor:constructors1){
            *//**
             * 结果:
             * public com.Jevin.blog.Student(java.lang.String)
             * public com.Jevin.blog.Student()
             *//*
            System.out.println(constructor);


            *//**
             * 结果:
             * public com.Jevin.blog.Student(String arg0)
             * public com.Jevin.blog.Student()
             * 这样写也可以,但是有点麻烦,所以不建议;
             *//*
            //获取权限修饰符:
            int mod=constructor.getModifiers();
            String modifier=Modifier.toString(mod);
            System.out.print(modifier+" ");
            //获取方法名:
            String methodName=constructor.getName();
            System.out.print(methodName+"(");
            //获得参数:
            Class[] cArgs=constructor.getParameterTypes();
            for(int i=0;i<cArgs.length;i++){
                System.out.print(cArgs[i].getSimpleName()+" arg"+i);
                if(i<cArgs.length-1){
                    System.out.print(",");
                }
            }
            System.out.print(")");
            System.out.println();
        }*/




        //2.通过"getDeclaredConstructors()"获取本类中所有的构造方法,包括public,protected,default,private;
        /**
         * 结果:
         * private com.Jevin.blog.Student(java.lang.String,java.lang.String,int)
         * com.Jevin.blog.Student(java.lang.String,int)
         * protected com.Jevin.blog.Student(int)
         * public com.Jevin.blog.Student(java.lang.String)
         * public com.Jevin.blog.Student()
         */
        /*Constructor[] constructors=clazz.getDeclaredConstructors();
        for(Constructor constructor:constructors){
            System.out.println(constructor);
        }*/




        //3.通过"getConstructor(class... paramterType)"获得指定的含有特定参数的public构造方法:
        /**
         * 结果:
         * public com.Jevin.blog.Student(java.lang.String)
         */
        //Constructor constructor=clazz.getConstructor(String.class);
        //System.out.println(constructor);




        //4.通过"getDeclaredConstructor(Class... paramterType)"获取本类中指定的含有特定参数的构造方法:
        //Constructor constructor=clazz.getDeclaredConstructor(int.class);
        /**
         * 结果:
         * protected com.Jevin.blog.Student(int)
         */
        //System.out.println(constructor);



        //5.那么,能否获得private修饰的构造方法呢?
        Constructor constructor= clazz.getDeclaredConstructor(String.class,String.class,int.class);
        /**
         * 结果:private com.Jevin.blog.Student(java.lang.String,java.lang.String,int)
         * 答案是可以的。
         *
         */
        System.out.println(constructor);

        //实例化对象:
        /**
         * 结果:
         * 私有的构造方法:stuNo=702,className=三中,score=59
         * com.Jevin.blog.Student@4554617c
         */
        constructor.setAccessible(true);
        Student student=(Student)constructor.newInstance("702","三中",59);
        System.out.println(student);
    }
}

三:利用反射获取类中的成员变量:

package com.Jevin.blog;

import java.lang.reflect.Field;

/**
 * 利用反射获取类中的成员变量:
 * 四种:getFields(),getField(String arg),getDeclaredFields(),getDeclaredField(String arg);
 */
public class VariableTest {
    public static void main(String[] args) throws Exception {

        Class clazz=Class.forName("com.Jevin.blog.Student");

        /**
         * 1.利用getFeilds()获取本类及其父类中所有public修饰的成员方法:
         *
         * 结果:public java.lang.String com.Jevin.blog.Student.stuNo
         *        public java.lang.String com.Jevin.blog.Person.name
         */
        /*Field[] fields=clazz.getFields();
        for(Field field:fields){
            System.out.println(field);
        }*/

        /**
         * 2.利用getField(String arg)获取本类中指定的public修饰的成员方法:
         *
         * 结果:public java.lang.String com.Jevin.blog.Student.stuNo
         */
        /*Field field=clazz.getField("stuNo");
        System.out.println(field);*/

        /**
         * 3.利用getDeclaredFields()获取本类中所有的成员变量:包括public,protected,default,private修饰的:
         *
         * 结果:
         * public java.lang.String com.Jevin.blog.Student.stuNo
         * protected java.lang.String com.Jevin.blog.Student.className
         * int com.Jevin.blog.Student.score
         * private java.lang.String com.Jevin.blog.Student.hobby
         */
        /*Field[] fields=clazz.getDeclaredFields();
        for(Field field:fields){
            System.out.println(field);
        }*/

        /**
         * 4.利用getDeclaredField(String arg)获取本类中指定的成员变量,不论是public,protected,defaul,private中的哪一种。
         *
         * 结果:private java.lang.String com.Jevin.blog.Student.hobby
         */
        Field field=clazz.getDeclaredField("hobby");
        System.out.println(field);
    }
}

四:利用放射获取类中的成员方法:

package com.Jevin.blog;

import java.lang.reflect.Method;

/**
 *利用反射类型获取成员方法:
 * 四种:getMethods(),getMethod(String arg,Class... paramterType),getDeclaredMethods(),getDeclaredMethod(String arg,Class... paramterType)
 */
public class MethodTest {
    public static void main(String[] args) throws Exception {

        Class clazz=Class.forName("com.Jevin.blog.Student");

        /**
         * 1.利用getMethods()获取本类中及其父类中所有的public修饰的成员方法:
         *
         * 结果:public void com.Jevin.blog.Student.test(int,boolean)
         *       public void com.Jevin.blog.Person.love()
         *       当然这里还有从Object父类中继承来的public方法,这里就不写了。
         */
        /*Method[] methods=clazz.getMethods();
        for(Method method:methods){
            System.out.println(method);
        }*/

        /**
         * 2.利用getMethod(String arg,Class... paramterType)获取本类中public修饰的成员方法
         * 第一个参数表示:方法名
         * 第二个参数表示:方法中参数的反射类型
         *
         * 结果:public void com.Jevin.blog.Student.test(int,boolean)
         */
        /*Method method=clazz.getMethod("test",int.class,boolean.class);
        System.out.println(method);*/

        /**
         * 3.利用getDeclaredMethods()获取本类中所有权限的成员方法,包括public,private,protected,default
         *
         * 结果:
         * public void com.Jevin.blog.Student.test(int,boolean)
         * void com.Jevin.blog.Student.getScore(java.lang.String)
         * private void com.Jevin.blog.Student.CEE(java.lang.String)
         * protected void com.Jevin.blog.Student.hateScore(double)
         */
        /*Method[] methods=clazz.getDeclaredMethods();
        for(Method method:methods){
            System.out.println(method);
        }*/

        /**
         * 4.利用getDeclaredMethod(String arg,Class... paramterType)货期本类中任意权限下的成员方法
         *
         * 结果:private void com.Jevin.blog.Student.CEE(java.lang.String)
         */
        Method method=clazz.getDeclaredMethod("CEE",String.class);
        System.out.println(method);
    }
}
//如果我要利用放射调用Student类中的getScore(String str)方法
@Test
public void test(){
    Class clazz = Student.class;
    Student student = (Student)clazz.newInstance();
    //第一个参数是String类型,表示调用的方法名称。
    //第二个参数是这个调用方法的参数的Class对象
    Method method = clazz.getMethod("getScore", String.class);
    //invoke方法,第一个参数是该方法所在类的对象。
    //第二个参数是该方法参数的对象
    method.invoke(student, new String());
}

 

好了,大致上最基本的就这些了。其他的更高深的等以后段位高了再发吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值