Android 中java反射应用(二)——应用篇
来源:互联网 发布:淘宝当当网是正品吗 编辑:程序博客网 时间:2024/06/06 01:38
JAVA反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
个人认为反射的精髓在于两个字—动态。我们在实际编程解决问题的时候,往往会遇到这种情况,就是程序运行的时候应该去实例化哪个类,只有在运行时才知道,因此不能够在编译阶段就做出决定。Java反射就可以帮助我们在运行时决定应该实例化哪个类。因此,java反射的强大就在于它能够在程序运行时实例化对象,这是同我们平时用new实例化对象最根本的区别。
首先来看看用反射机制和用以前的方法新建对象实例有什么不同
第一步新建一个Person对象
用以前的方法是:
Person p = new Person();
在内存中新建一个Person的实例,对象p对这块内存地址进行引用
用反射机制实现 (有三种方法):
第一种:
Class<?> cls=Class.forName("com.fanshe.Person"); //forName(包名.类名)
Person p=(Person)cls.newInstance();
1.通过JVM查找并加载指定的类(上面的代码指定加载了com.fanshe包中的Person类)
2.调用newInstance()方法让加载完的类在内存中创建对应的实例,并把实例赋值给p
第二种:
Person p = new Person();
Class<?> cls=p.getClass();
Person p2=(Person)cls.newInstance();
1.在内存中新建一个Person的实例,对象p对这个内存地址进行引用
2.对象p调用getClass()返回对象p所对应的Class对象
3.调用newInstance()方法让Class对象在内存中创建对应的实例,并且让p2引用实例的内存地址
第三种:
Class<?> cls=Person.Class();
Person p=(Person)cls.newInstance();
1.获取指定类型的Class对象,这里是Person
2.调用newInstance()方法在让Class对象在内存中创建对应的实例,并且让p引用实例的内存地址
注意:
cls.newInstance()方法返回的是一个泛型T,我们要强转成Person类
cls.newInstance()默认返回的是Person类的无参数构造对象
被反射机制加载的类必须有无参数构造方法,否者运行会抛出异常
先来看看反射的好处
可能有人会有疑问,明明直接new对象就好了,为什么非要用反射呢?代码量不是反而增加了?
其实反射的初衷不是方便你去创建一个对象,而是让你在写代码的时候可以更加灵活,降低耦合,提高代码的自适应能力.
怎么样降低耦合度,提高代码的自适应能力?
通过接口实现,但是接口如果需要用到new关键字,这时候耦合问题又会出现
举个栗子:
public static void main(String[] args) { HeroFacrty facrty =new HeroFacrty(); hero iroman= facrty.CreateHero("IronMan"); iroman.attach();}public hero CreateHero(String name) { if ((name).equals("IronMan")) { return new IronMan(); } if ((name).equals("Hulk")) { return new Hulk(); } return null;}interface hero { public void attach();}class IronMan implements hero { @Override public void attach() { System.out.println("Laser Light"); }}class Hulk implements hero { @Override public void attach() { System.out.println("fist"); }}
假设有1000个不同Hero需要创建,那你打算写1000个 if语句来返回不同的Hero对象?
如果使用反射机制呢?
public static void main(String[] args) { HeroFacrty facrty = new HeroFacrty(); Hero hero=facrty.CreateHero("test.IroMan"); hero.attack(); } public Hero CreateHero(String name) { try { Class<?> cls = Class.forName(name); Hero hero = (Hero) cls.newInstance(); return hero; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }}class IroMan implements Hero { @Override public void attack() { System.out.println("Laser Light"); }}class Hulk implements Hero { @Override public void attack() { System.out.println("Fist"); }}interface Hero { public void attack();}
利用反射机制进行解耦的原理就是利用反射机制"动态"的创建对象:向CreateHero()方法传入Hero类的包名.类名 通过加载指定的类,然后再实例化对象.
对于反射机制举个不太严谨的栗子:
当你电脑需要使用鼠标时,你向电脑USB接口插入鼠标,鼠标向电脑发送驱动请求,驱动的型号为NFTW-2196的驱动.这时候电脑在驱动集合中查找驱动,找到后运行驱动鼠标能用了,插入键盘同理.
说完了反射机制如何生成类对象,那生成了对象以后当然要开始调用类的方法了
在调用方法前先了解Class<?> cls=Class.forName("fanshe.Person");
cls内部有哪些方法供我们使用.
以下面的Person来做讲解,稍后我们会用反射实现下面的代码:
public class fanshe03 { public static void main(String[] args) { Person person=new Person(); person.setName("Lipt0n"); System.out.print(person.getName); }}class Person { String name; public Person() { } public Person(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }
很简单步骤分为三步:
- 实例化一个Person类对象
- 调用Person.setName("name")设置名字
- 在控制台打印Person.getName()的值
现在我们用反射机制来实现上面的代码:
public static void main(String[] args) { try { Class<?> cls=Class.forName("test.Person");//加载Person类 Object object=(Object) cls.newInstance();//实例化Person Method setname=cls.getDeclaredMethod("setName", String.class);//获取setName()方法 setname.invoke(object, "Lipt0n");//设置调用setName的对象和传入setName的值 Method getname=cls.getDeclaredMethod("getName");//获取getName方法 System.out.print(getname(object, null));//设置调用getName方法的对象.把值打印到控制台 } catch (Exception e) { e.printStackTrace(); } }
Java程序可以加载一个运行时才得知名称的class,获悉其完整构造,并生成其对象实体、或对其成员变量赋值、或调用其方法。这种“看透class”的能力称为反射.--(摘自网上的一段话,具体出处忘记了)
- Android 中java反射应用(二)——应用篇
- Android 中java反射应用(三)——应用场景及总结
- Android 中java反射应用(一)——基础篇
- Android中java反射的应用
- 反射应用(二)
- 反射应用(二)
- Java反射原理及应用(二)
- java反射技术的应用(二)
- java之反射技术应用(二)
- Java基础之反射(二):反射应用
- Java中反射(Reflection)的应用
- Java中反射(Reflection)的应用
- android中反射的应用
- java 中反射的应用
- Java Socket应用(二)——java中InetAddress的应用
- java基础——反射的应用
- Java——反射概念、应用
- Java反射API(应用篇)
- 软件开发模型之瀑布模型
- iOS
- 我的java学习路之编写第一个程序
- phpstorm version 2016.2 License Server激活
- [摘抄-Java-学习中]Java 图片叠加水印&文字自动换行
- Android 中java反射应用(二)——应用篇
- EasyUI DataGrid中URL中文乱码的解决办法
- C#的异步编程模式
- ListView实现隐藏,显示Item的部分View.以及部分问题
- 微信公众号开发(一)——开发模式接入,消息的接收与响应
- 通过ricequant监测雪球舆情数据
- LeetCode Weekly Contest 30
- Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
- 配好caffe后,编译MATLAB接口