高级Java思考笔记之反射的基本原因之一
发布时间:2021-11-04 14:21:09  所属栏目:语言  来源:互联网 
            导读:原来我一直将java当做不用delete的c++来用,但是最近在工作上遇到一些问题,发现这样的做法不管用,因为工作上遇到的java代码采用了很多框架,例如spring boot之类。当我想深入了解这些框架的设计原理时发现,如果不了解java的高级语法特性,这些框架的设计
                
                
                
            | 原来我一直将java当做不用delete的c++来用,但是最近在工作上遇到一些问题,发现这样的做法不管用,因为工作上遇到的java代码采用了很多框架,例如spring boot之类。当我想深入了解这些框架的设计原理时发现,如果不了解java的高级语法特性,这些框架的设计思维或运行方式根本就无法理解。
	 
	后来稍微调查一下发现,自从java8之后,java的语法发生了巨大的变化,代码的设计模式也不再像以前“不用delete的c++”,参照原来c++的思维去解读java代码已经行不通了,于是重新学习,顺便在学习和思考中做一些总结输出。
	 
	java新增语法特征中,有较为抽象的一部分叫反射,其实说白了就是用程序来控制程序。java将一切概念都包含在类中,于是对应每一个具体类,语言体系还为特定的具体类生成了描述其特性的抽象类,例如我们定义了如下一个类:
	 
	static public class HelloWorld { 
	    public void sayHelloWorld1(String s) { 
	           System.out.println("say hello world 1!: " + s); 
	       } 
	 
	       public void sayHelloWorld2(int i) { 
	           System.out.println("say hello world 2: " + i); 
	       } 
	 
	       protected  void sayHelloWorld3() { 
	           System.out.println("say hello world3"); 
	       } 
	 
	       private void sayHelloworld4() { 
	           System.out.println("say hello world4"); 
	       } 
	 
	       public String field1 = "hello"; 
	       protected int field2 = 1; 
	       private int field3 = 2; 
	 
	   } 
	这个类里面有公有,保护,私有等几个方法,虚拟机在为这个类生成字节码时,还构建了另一个类,用于描述这个类的类,可以称为它的源类,后者用来描述前者在编程语言上的特性,例如它包含了哪些方法,这些方法对应的参数,返回值,公有私有等,如果把一个类比作人,那么反射其实就是x光扫描,它把你内外的具体细节都暴露出来,我们看看怎么用反射来解读上面定义的类:
	 
	public static void manipulateHelloWorldClass(Object obj) { 
	        Class cls = obj.getClass(); 
	        //打印出类对象对应的类名 
	        System.out.println("object class name: " + cls.getName()); 
	        //返回实例对应的类所声明的所有函数 
	        Method[] methods = cls.getDeclaredMethods(); 
	        for (Method method : methods) { 
	            System.out.println("delcared method name: " +  method.getName()); 
	        } 
	    } 
	 
	    public static void main(String[] args) { 
	        HelloWorld helloWorld = new HelloWorld(); 
	        manipulateHelloWorldClass(helloWorld); 
	    } 
	上面代码运行后输出结果如下:
	 
	 
	 
	可以看到,代码打印出helloword实例对象在编程语言上的信息,例如上面代码就打印出它对应类的名字,都有哪些方法等等,在Java语言中Class类也叫原类,它用来解析所有实例对应类在编程语法上的信息,每个实例对应的类都能得到一个Class类对应的实例,就像代码中那样,这个实例能够查询对应类有哪些方法,定义了哪些字段.
	 
	代码中调用了getDeclaredMethods来获得实例所对应类在定义时声明的所有方法,Class类还有一个方法叫getMethods,它返回实例对应类自己在定义时所声明的公有方法,以及继承过来的所有公有方法。
	 
	反射机制一个很重要的作用就是能够查询给定实例是否有特定接口,然后调用相关接口,代码如下:
	 
	public static void callMethod(Object obj) { 
	        Class cls = obj.getClass(); 
	        try { 
	            Method method = cls.getMethod("sayHelloWorld1", new Class[] {String.class}); 
	            method.invoke(obj, new Object[]{"hello world"}); 
	            method = cls.getMethod("sayHelloWorld2", new Class[] {int.class}); 
	            method.invoke(obj, new Object[]{new Integer(123)}); 
	        } catch(NoSuchMethodException e) { 
	            e.printStackTrace();; 
	        } catch (IllegalAccessException e) { 
	            throw new IllegalArgumentException("Insufficient access permissions to call" 
	                    + "setColor(:Color) in class " + cls.getName()); 
	        } catch (InvocationTargetException ex) { 
	            throw new RuntimeException(ex); 
	        } 
	 
	    } 
	 
	    public static void main(String[] args) { 
	        HelloWorld helloWorld = new HelloWorld(); 
	      //  manipulateHelloWorldClass(helloWorld); 
	        callMethod(helloWorld); 
	    } 
	上面代码执行后结果如下所示:
	 
	 
	 
	我们可以体会到,c++是不会有这种特性的,java由于具备了这种反射机制,使得它能够用来开发很多框架,在java世界里形形色色的框架特别多,这跟它在语法上支持反射不无关系,类似spring boot这些java程序员绝对必须要掌握的框架,它的设计就大量使用了反射机制。 (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! | 

