java的反射

前言

本篇是之前java反射学习的回顾,主要以详细的代码Demo为主,关于反射的细节不做介绍,具体的详细介绍参考一位大神的博客

——–传送门———

Class类

  • 在面向对象的世界里,万事万物皆对象。
  • 类是对象,类是java.lang.Class类的实例对象。

话不多说Demo里面详解:

package PackageOne;

public class JavaClass {

    public static void main(String[] args) {
        foo f1=new foo();
        //任何一个类都是Class的实例对象,有三种表达方式
        // 1,任何一个类都有一个隐含的静态成员变量class
        Class c1=foo.class;

        // 2,已知道该类的对象可以通过getClass方法
        Class c2=f1.getClass();
        //c1,c2表示了foo类的 类类型,    
        System.out.println(c1==c2);//true

        // 3,第三种表达方式
        Class c3 = null;

        try {
            //括号里面写的是类的全称
            c3=Class.forName("PackageOne.foo");
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        }
        System.out.println(c2==c3);//true

        //可以通过类的类类型创建该类的对象实例,通过c1,c2,c3创建foo类
        foo f2 = null;
        System.out.println(f2==f1);//false
        System.out.println(f1.equals(f2));//false

        try {
            f2=(foo)c1.newInstance();//需要有无参数的构造方法
            f2.print();//正确执行
        } catch (InstantiationException e) {            
            e.printStackTrace();
        } catch (IllegalAccessException e) {            
            e.printStackTrace();
        }

        /* f2不是foo对象是因为没有被 new 出来 */
        System.out.println((f2==f1)+"...");//false
        System.out.println(f1.equals(f2)+"...");//false

    }

}

class foo{
    public foo(){}
    public void print(){
        System.out.println("foo...");
    }

}

总结:

任何一个类都是Class的实例对象,有三种表达方式

以例子中的foo类举例子
1. 任何一个类都有一个隐含的静态成员变量class

Class c1=foo.class;

  1. 已知道该类的对象可以通过getClass方法

Class c2=f1.getClass();

  1. 第三种表达方式
Class c3 = null;
c3=Class.forName("PackageOne.foo");

反射

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制获取对象的方法

package Java_Reflect;

import java.lang.reflect.Method;

public class Method1 {

        public static void main(String[] args) {
           /*要获取print(int ,int )方法 
            1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型
            */
            A a1 = new A();
            Class c = a1.getClass();
            /*
             * 2.获取方法 名称和参数列表来决定  
             * getMethod获取的是public的方法
             * getDelcaredMethod自己声明的方法
             */
            try {
                //Method m =  c.getMethod("print", new Class[]{int.class,int.class});//效果等同
                Method m = c.getMethod("print", int.class,int.class);

                /*
                 * 方法的反射操作 
                 * MethodName.invoke(ClasasName,a,b...);
                 * 1. ClassName:类名
                 * 2. a,b... :参数 
                 * a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同
                 * 方法如果没有返回值返回null,有返回值返回具体的返回值
                 */
                //Object o = m.invoke(a1,new Object[]{10,20});
                Object o =m.invoke(a1, 10,20);                
                System.out.println("==================");
                //获取方法print(String,String)
                 Method m1 = c.getMethod("print",String.class,String.class);
                 //用方法进行反射操作
                 //a1.print("hello", "WORLD");
                 m1.invoke(a1, "hello","WORLD");
                 System.out.println("===================");
               //  Method m2 = c.getMethod("print", new Class[]{});
                    Method m2 = c.getMethod("print");
                   // m2.invoke(a1, new Object[]{});
                    m2.invoke(a1);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 

        }
}
    class A{
        public void print(){
            System.out.println("helloworld");
        }
        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());
        }
    }

反射方法绕过泛型的例子

package Java_Reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;

public class Method2 {

    public static void main(String[] args) {
        LinkedList<String>list1=new LinkedList<String>();
        LinkedList<Integer> list2=new LinkedList<Integer>();
        list1.add("asd");
        list2.add(30);
        //list1(20);//提示错误。因为20不是string类型
        Class c1 = list1.getClass();
        Class c2 = list2.getClass();
        System.out.println(c1==c2);
        //反射的操作都是编译之后的操作

        /*
         * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
         * Java中集合的泛型,是防止错误输入的,只在编译阶段有效,
         * 绕过编译就无效了
         * 验证:我们可以通过方法的反射来操作,绕过编译
         */
        try {
            //通过方法的反射来操作,绕过编译
            Method m1 = c1.getMethod("add",Object.class);
            m1.invoke(list1, 10);
            System.out.println(list1);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException 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();
        }

        try {
            Method m2 = c2.getMethod("add", Object.class);
            m2.invoke(list2, "hello world!!!");
            System.out.println(list2);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException 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();
        }

    }
}

反射的动态代理

接口实现类测试类
OfficeAble.javaWord.java,Excel.javaOffice.java

OfficeAble.java:

package ReflectDemo_1;

interface  OfficeAble {
    public void start();
}

Word.java:

package ReflectDemo_1;

public class Word implements OfficeAble{
    public void start() {
        System.out.println("Word.....");

    }
}

Excel.java:

package ReflectDemo_1;

public class Excel implements OfficeAble{

    public void start() {
        System.out.println("Excel.....");
    }

}

Office.java:

package ReflectDemo_1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class Office {

    public static void main(String[] args) {
        InputStreamReader in = new InputStreamReader(System.in);
        BufferedReader bf = new BufferedReader(in);
        String nameString=null;
        try {
            nameString = bf.readLine();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            //创建class对象
            Class c1=Class.forName("ReflectDemo_1."+nameString);
            try {
                //强转为OfficeAble接口对象
                OfficeAble oa = (OfficeAble)c1.newInstance();               
                oa.start();
            } catch (InstantiationException e) {                
                e.printStackTrace();
            } catch (IllegalAccessException e) {                
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值