• Java 反射机制


    1.Class 类

      所有的类都是java.lang.Class类的实例。 通过a1,a2,a3,a4四种方式获得Class类实例。

      通过已知不同的条件,或者为类名A,可通过Class a1 = A.class方式获取类,如果知道实例可以通过Class a2 = a.getClass();效果一样。

    public class AboutClass {
        public static void main(String[] args) {
            A a = new A();
            Class a1 = A.class;  //任何事物皆是对象,类A是Class类的对象
            Class a2 = a.getClass();  //a1,a2 表示了A类的类类型
            System.out.println("a1=a2是"+(a1==a2));
            try{
                Class a3 = Class.forName("com.project.reflect.A"); //全路径
                System.out.println("a1=a3是"+(a1==a3));
            }catch(Exception e){
                e.printStackTrace();
            }
            try {
                A a4 = (A) a1.newInstance(); //A必须有无参构造方法
                a4.print();
            } catch (Exception e) {
                
                e.printStackTrace();
            } 
            
        }
    }
    
    class A{
        public A(){
            
        };
        public void print(){
            System.out.println("this is A");
        }
    }

    运行结果为:

                             

    2、静态加载&动态加载

     静态加载类:编译时加载,指的是通过new创建的对象,在编译时加载所有可能用到的类。

     动态加载类:运行时加载类。 Class.forName("类的全称")

    例子:

    如果在记事本上,编写一个类如下:

    public class  Test{
        public static void main(String args[]){
            
            if("Word".equals(args[0])){
                Word.start();
            }
            else if("Excel".equals(args[0])){
                Excel.start();
            }
            
        }
    }

    通过cmd命令行,编译javac时,会报错,找不到Word类、找不到start()方法、Excel类、找不到start()方法,四个错误。

    假如我们已经有了一个Word类,Word类中存在start()方法,并且已经编译过。则仍然报错找不到Excel类、找不到start()方法,两个错误。

    这就造成了,本来是运行word,却因为excel报错而无法运行。

    然后,我们对程序做如下修改:

    1.创建一个OfficeRef接口

    public interface OfficeRef{
        public void start();
    }

    2.创建Word类继承OfficeRef接口

    public class Word implements OfficeRef{
        public void start(){
            System.out.println("word starting...");
        }
    }

    3.将Test类做如下修改

    public class  Test{
        public static void main(String args[]){
            if("Word".equals(args[0])){
                try{
                    Class c = Class.forName(args[0]);  //动态加载类,通过类类型创建Class对象(全路径)
                    OfficeRef off = (OfficeRef)c.newInstance(); //根据实例创建类
                    off.start();
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    在cmd命令下,首先编译OfficeRef,然后word,然后编译Test类,最后运行  java Test Word 发现可以成功运行

    此处Word换成excel依然可以。这就是动态加载类的好处。

    功能性的类使用动态加载。

     3.反射--获取方法的信息

    public class ReflectClass{ 
        public static void main(String[] args) {
            Class c1 = int.class; //int的类类型
            Class c2 = String.class; 
            Class c3 = double.class;
            Class c4 = Double.class;
            Class c5 = void.class; //所有类中的元素,都含有类类型
            
            System.out.println(c1.getName());
            System.out.println(c2.getName());
        }
    }
    public class ClassUtil {        
        public static  void getMethodRef(Object obj){
            Class c = obj.getClass();
            c.getName();
            Method[] ms = c.getMethods(); //获取的是所有的public类型的,包括从父类中继承的方法
            Method [] mms = c.getDeclaredMethods();//获取的是所有的自己类声明的方法;
            for(int i=0;i<ms.length;i++){
                System.out.println(ms[i].getName());
                Class returnType = ms[i].getReturnType(); //返回的是返回类型的类类型
                System.out.println(returnType.getName());
                Class []paraType=ms[i].getParameterTypes(); //参数类型的类类型
                for(Class param:paraType){
                    System.out.print(param.getName()+",");
                }
            }    
        }
    }
    public class Demo {
        public static void main(String[] args) {
            String s ="Hello";
            ClassUtil.getMethodRef(s);
        }
    }

    4.获取成员变量构造函数信息

    成员变量也是对象,是java.lang.reflect.Filed Filed类获得了封装关于成员变量的操作

    Filed fs[] =c.getFileds()

  • 相关阅读:
    hihocoder 1489(微软2017, 数学,模拟)
    图论——迪杰斯特拉算法(Dijkstra)实现,leetcode
    DFS,BFS 练习(深搜,广搜,图,leetcode)
    什么是渗透测试?黑客安全专家郭盛华这样说
    为什么印度容易遭受网络黑客攻击?
    郭盛华年收入5000万是真的吗?
    警方突袭德国间谍软件公司
    苹果推出首款5G手机,相机功能比单反还要牛?
    苹果推出iPhone 12,价格比你想象中更实惠
    韩国AI半导体技术,为何能问鼎世界第一?
  • 原文地址:https://www.cnblogs.com/doudingbest/p/4965061.html
Copyright © 2020-2023  润新知