首页 > 编程 > Java > 正文

Java反射

2019-11-08 03:08:01
字体:
来源:转载
供稿:网友

反射

一、     Class类的使用

法一:知道类,创建类实例

Class c1=Foo.class;

Class c2=int.lass

Class c3=double.class;

法二:知道对象,创建类实例

Food foo=new Food();

Class c2=foo.getClass();

类也是对象,Class类的实例对象,类的类类型

法三:知道String,创建类实例

Class c3=Class.forName(“com.lrq.entity”);

//通过类的类型创建该类的对象实例

Food food=(Food)c3. newInstance();

 

 

二、     Class类的动态加载

Ø  Class c=Class.forName(args[0]);

Ø  OfficeAble oa=(OfficeAble)c.newInstance();

Ø  oa.start();

Ø  将OfficeAble作为一个接口

 

1.创建OfficeBetter类:

2.创建OfficeAble类:

3.创建Word实现OfficeAble接口:

 

编译与运行:(先将OfficeBetter,OfficeAble,Word编译成字节码,最后输入类名执行)

三、    获取方法信息

public classClassUtil1 {

    /**

     * 1.输入类对象,打印出对象的类名

     * 2.打印出对象的方法名

     * 3.打印出对象的返回值类型

     * 4.打印出对象的参数列表

     * @param o

     */

    public static void showClassMessage(Objecto){

        Class c1=o.getClass();

        System.out.PRintln("类的对象名:"+c1.getName());

       System.out.println("================================");

        Method[] methods=c1.getMethods();

        for (Method m:methods){

            System.out.println("类的方法名:"+m.getName());

            System.out.println("类的返回值类型:"+m.getReturnType());

            Class[]paramType=m.getParameterTypes();

            for (Class p:paramType){

                System.out.print("类的参数列表:"+p.getName()+"/n");

            }

           System.out.println("==================================");

        }

    }

}

四、    获取成员变量,构造函数信息

成员变量:

  /**

         * 成员变量也是对象

         * java.lang.reflect.Fields

         * 封装了关于成员变量的操作

         *getFields()方法获取的是所有public的成员变量的信息

         * getDeclaredFields获取是该类自己声明成员变量的信息

         */

        /*Field[] fields=c.getFields();*/

        Field[] fields=c.getDeclaredFields();

        for(Field fs:fields){

            //得到成员变量的类类型

            Class fieldType=fs.getType();

            Stringtypename=fieldType.getName();

            //得到成员变量的名称

            String fieldName=fs.getName();

           System.out.println(typename+":"+fieldName);

}

构造函数信息:

  /**

     * 打印构造函数信息

     */

    public static void printConmessage(Objecto){

        Class c=o.getClass();

        /**

         * 构造函数也是对象

         * java.lang.Constryctor中封装了构造函数信息

         * getConstructors获取所有public的构造函数

         * getDeclaredConstructors得到所有构造函数

         *

         */

        //获取所有构造函数

        Constructor[]con=c.getDeclaredConstructors();

        for(Constructor co:con){

            //构造函数名

            System.out.print(co.getName()+"(");

            //构造函数参数列表----》获取参数列表类类型

            Class[]paramTypes=co.getParameterTypes();

            for(Class p:paramTypes){

               System.out.print(p.getName()+",");

            }

            System.out.println(")");

 

        }

 

    }

 

 

 

 

 

 

五、    方法反射(Class,Method,invoke)

public classMethodReflect {

    public static void main(String[] args) {

        A a1=new A();

        Class c=a1.getClass();

        //指定方法:方法名+参数列表

        try {

            Methodm=c.getMethod("print",int.class,int.class);

            /*Object o=m.invoke(a1,newObject[]{10,20});*/

            Object o=m.invoke(a1,10,20);

            Methodm1=c.getMethod("print",String.class,String.class);

           o=m1.invoke(a1,"hi","man");

            Methodm2=c.getMethod("print");

            m2.invoke(a1);

        } catch (Exception e) {

            e.printStackTrace();

        }

}

==================================================

    static class A{

        public void print(){

           System.out.println("Hi,Man");

        }

        public void print(int a,int b){

            System.out.println(a+b);

        }

        public void print(String a,String b){

           System.out.println(a.toUpperCase()+b.toLowerCase());

        }

    }

}

 

 

六、    了解集合泛型的本质

1.   Java的泛型只在编译阶段有效,目的是为了错误类型输入

2.   编译之后去泛型化,可以通过反射来绕过编译

public classMethodDemo {

    public static void main(String[] args) {

        ArrayList list=new ArrayList();

        ArrayList<String> list1=newArrayList<String>();

        list1.add("hello");

        Class c1=list.getClass();

        Class c2=list1.getClass();

        System.out.println(c1==c2);

        //反射的操作均是编译之后操作

 

        /**

         * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的

         *Java中集合的泛型,是防止错误输入的,只在编译阶段有效

         * 绕过编译无效

         * 验证:我们可以通过方法的反射来操作,绕过编译

         */

        try {

            Methodm=c2.getMethod("add", Object.class);

            m.invoke(list1,20);//绕过编译操作就绕过了泛型

            System.out.println(list1.size());

            System.out.println(list1);

            System.out.println(list==list1);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表