java高级开发学习之--反射机制(3)
2016-08-11 21:13
411 查看
1.通过前面的学习,自己感觉其实反射机制也没有很神秘,无非就是类本身就是一个对象,通过类的类类型去动态加载类。
2.今天学习类的方法的反射操作以及通过反射来了解集合泛型的本质。
A.方法的反射操作:
首先我们创建一个类
接着创建测试类
在测试类中有详细的注释:那么是什么意思呢,简单理解
本来调用类A中的print()方法时,我们得通过new A()创建A类的对象才能调用print()方法,也就是
而学习了反射后,我们发现调用print()方法还有别的方式
1.我们首先通过
2.通过
第一个参数代表 你所要获取的方法名;第二个是多参类型,表示你所要获取的方法的参数列表的参数类类型。
接着通过invoke方法来执行方法的反射操作
至此,方法的反射操作即完成了。当然如果想调用A类的print(String a, String b)方法也是一样的操作了
B.通过反射了解集合泛型的本质:
完整代码如下:
很简短的几行代码,但是让我更深的理解了泛型的本质.
为什么
而当我们用反射来操作add方法时,却可以添加20,这是因为反射的操作是在编译之后执行的,因此,编译之后不存在泛型,所以可以添加20.
至此,我们可以指定泛型其实就是为了防止错误输入的,它并不神秘,它只在编译阶段有效,绕过编译就无效了。
2.今天学习类的方法的反射操作以及通过反射来了解集合泛型的本质。
A.方法的反射操作:
首先我们创建一个类
class A{ 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()); } }
接着创建测试类
public class ClassDemo2 { public static void main(String[] args) { A a1 = new A(); Class c = a1.getClass(); try { // Method m = c.getMethod("print", new Class[]{int.class,int.class}); Method m = c.getMethod("print", int.class,int.class); //方法的反射操作 //a1.print(10, 20); 方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同 //方法如果没有返回值返回null,有返回值返回具体的返回值 Object o = m.invoke(a1,new Object[]{10,20}); System.out.println("******************"); //获取方法print(String,String) Method mt = c.getMethod("print", String.class,String.class); o = mt.invoke(a1, "abcA","Acv"); } catch (Exception e) { e.printStackTrace(); } } }
在测试类中有详细的注释:那么是什么意思呢,简单理解
本来调用类A中的print()方法时,我们得通过new A()创建A类的对象才能调用print()方法,也就是
A a = new A(); a.print(10,20);
而学习了反射后,我们发现调用print()方法还有别的方式
1.我们首先通过
Class c = a.getClass();获取a对象的类类型。
2.通过
Method m = c.getMethod("print",int.class,int.class);获取print方法。
public Method getMethod(String name, Class<?>... parameterTypes)
第一个参数代表 你所要获取的方法名;第二个是多参类型,表示你所要获取的方法的参数列表的参数类类型。
接着通过invoke方法来执行方法的反射操作
//方法如果没有返回值返回null,有返回值返回具体的返回值 //第一个参数是所要执行方法操作的对象,后面则是方法参数列表所要传的实际参数 Object o = m.invoke(a1,new Object[]{10,20});
至此,方法的反射操作即完成了。当然如果想调用A类的print(String a, String b)方法也是一样的操作了
//获取方法print(String,String) Method mt=c.getMethod("print",String.class,String.class); o = mt.invoke(a1, "abcA","Acv");
B.通过反射了解集合泛型的本质:
完整代码如下:
public class ClassDemo3 { public static void main(String[] args) { ArrayList list = new ArrayList(); ArrayList<String> list1 = new ArrayList<String>(); list1.add("hello"); //list1.add(20); 错误的,因为规定了类型为String Class c1 = list.getClass(); Class c2 = list1.getClass(); System.out.println(c1 == c2); //反射的操作都是编译之后的操作 /** * c1==c2结果返回true 说明编译之后集合的泛型是去泛型化的 * java中集合的泛型,是防止错误输入的,只在编译阶段有效 * 绕过编译就无效了 * 验证:我们可以通过方法的反射操作来绕过编译 */ try { Method m = c1.getMethod("add", Object.class); m.invoke(list1, 100); System.out.println(list1.size()); System.out.println(list1); } catch (Exception e) { e.printStackTrace(); } } }
很简短的几行代码,但是让我更深的理解了泛型的本质.
为什么
//list1.add(20);这个是错误的呢,首先list1定义了泛型,String类型,那么在编译时,相当于给你规定了类型,必须add String类型的参数才行,所以当然是不能add 20的,但是 c1是等于c2的,为什么呢,因为泛型在编译之后就被去掉了,也就是说
ArrayList<String> list1 = new ArrayList<String>();这行代码在编译后就变成了
ArrayList list1 = new ArrayList();所以c1最后是等于c2的。
而当我们用反射来操作add方法时,却可以添加20,这是因为反射的操作是在编译之后执行的,因此,编译之后不存在泛型,所以可以添加20.
至此,我们可以指定泛型其实就是为了防止错误输入的,它并不神秘,它只在编译阶段有效,绕过编译就无效了。
相关文章推荐
- java高级开发学习之--反射机制(1)
- java高级开发学习之--反射机制(2)
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- java学习之反射机制
- Java学习之-----反射机制
- java高级技术学习_反射
- Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制
- Java学习之反射机制的理解
- java学习之理解反射机制
- 深入浅出学习hibernate框架(三):java的反射机制
- 学习心得:Java为什么支持反射机制?
- Java的动态性支持学习二 - 反射机制 属性、方法、对象的操作
- Java反射的高级应用,模拟开发环境IDE动态搜索类成员以及方法,。。。。。
- 黑马程序员学习笔记之八(Java 反射机制)
- [学习小记]Java的反射机制
- Java的反射(reflect)机制的学习
- JAVA中的反射机制的学习
- Java中反射机制(Reflection)学习
- java学习之反射机制