-------
android培训、java培训、期待与您交流! ----------
一、反射概念
- 反射就是把Java类中的各种成分映射成相应的Java类。
- 例如,一个Java类中用一个Class类的对象来表示,
- 一个类中的组成部分:成员变量,方法,构造方法,包等信息也用一个个Java类来表示。
- 就像汽车是一个类,其中的发动机,变速箱等等也是一个类。
- 表示Java类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用相应类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
- 一个类中的每一个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象有什么用?怎么用?这正是学习和应用反射的要点。
- 理解:
- Java的类进入内存,变成一份份Java字节码文件,每一份字节码文件就是Class类的实例对象(因为Class类就是描述这些字节码文件的类,是所有字节码文件的类)。
- 字节码文件就是把所有类的字节码文件抽取出的共性(属性、方法、各种信息)封装为一个统一的Class类,而每个字节码文件就是这个Class类的一个实例对象,所以这些对象可以调用Class类的方法,如getMehod(),isPrimitive(),getConstructor()等等。
- 反射把这些组成部分封装起来
- 组成部分的字节码文件: Field、Method、Contructor、Package等,这些字节码文件是Class类的实例对象,这些实例对象提供了一些方法暴露自己的信息。
-
疑问?
- 这些字节码文件与要反射的类有什么关系呢?
- 比如说String.class.getConstructor();这一句是String的字节码字节码文件(Class类的实例对象)使用了 Contructor字节码文件 (Class类的实例对象)的 getConstructor()方法?
- 牢记:
- 得到Class的三种方法:
String str1 = "abc";
//得到Class的三种方法:对象.getClass,类.class,Class.forName("类名")
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
三、Field的反射
-
ReflectPoint pt1 = new ReflectPoint(3,5);
//通过字节码,得到Field类对象
Field fieldY = pt1.getClass().getField("y");
System.out.println(fieldY.get(pt1));//
//得到private的字段
Field fieldX = pt1.getClass().getDeclaredField("x");//private�����ɼ�
fieldX.setAccessible(true);//private�������Է���
System.out.println(fieldY.get(pt1));
四、Method的反射
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1,1));
System.out.println(methodCharAt.invoke(str1, new Object[]{2}));//JDK1.4
五、用反射调用其他类的main 方法。
//用反射调用其他的main方法
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
mainMethod.invoke(null, new Object []{new String[]{"111","222","333"}});
mainMethod.invoke(null, (Object)new String[] {"111","222","333"});
六、数组与Object及其反射类型
七、反射的作用-举例
-
例子来源:http://www.cnblogs.com/zxl-jay/archive/2011/09/25/2190585.html
-
需求:设计一个主板,为了提高后期的扩展性,也就是为了后期提高电脑的额功能,对外提供了PCI的接口。以方便电脑功能的扩展。
-
interface PCI{
void open();
void close();
}
class MainBoard{
public void usePCI(PCI p){
p.open();
p.close();
}
}
class MainBoardDemo{
public static void main(String[] args){
MainBoard mb=new MainBoard();
//mb.usePCI(null);
mb.usePCI(NetCard);
}
}
后期,要进行电脑功能的扩展,需加入一个网卡,只需要定义一个网卡类实现PCI接口,只要覆盖这个规则,主板就可以使用该板卡。
-
class NetCard implements PCI{
public void open();{
system.out.println("open");
}
public void close();{
system.out.println("close");
}
}
那么为了使用其网卡,还需要做一个步骤就是在已定义好的应用程序中,建立网卡对象,并作为参数传入,那么就是对原有的程序进行修改。这样不利于程序的健壮性。
可不可以在不修改源码的基础上运行后期出现的这些子类对象呢?
只要在前期设计时,将后期指定的类进行对象的建立,这样后期的子类对象就不需要再建立对象,只要将子类名称告知即可。
为了获取后期对象,并在前期可以使用,或对外提供了一个配置文件。前期程序可以直接操作该配置文件,后期的子类只需要将子类名称存入配置文件即可。
这时就需要动态的获取指定的类并预先创建对象
-
就用到了反射机制。重新修改一下应用程序。
class MainBoardDemo{
public static void main(String[] args){
MainBoard mb=new MainBoard();
File file=new File("conf.txt");
BufferenReader buff = new BufferenReader(new FileReader(file));
String className = buff.readLine();
Class clazz = Class.forName(className);
PCI p = (PCI)clazz.newInstance();
mb.usePCI(p);
}
}
-
配置文件conf.txt
当后期出现网卡或者声卡的时候,只需要将该子类的全类名存入配置文件即可, 源程序不需要进行修改
在该例中,可以了解,反射给我们的程序带来了很强的扩展性。
八、反射的作用-框架的概念
- 比如在反射中,调用一个未知类的main(),未知类是后来的。这个反射就实现了一个小框架。
- 框架是提前做好的,框架调用用户的类,就像房子是框架,新门是用户类。
- 反射做的框架有个好处:将来的类可以调用以前的类。框架不需要知道将来的类叫什么。
一、反射概念
- 反射就是把Java类中的各种成分映射成相应的Java类。
- 例如,一个Java类中用一个Class类的对象来表示,
- 一个类中的组成部分:成员变量,方法,构造方法,包等信息也用一个个Java类来表示。
- 就像汽车是一个类,其中的发动机,变速箱等等也是一个类。
- 表示Java类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用相应类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
- 一个类中的每一个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象有什么用?怎么用?这正是学习和应用反射的要点。
- 理解:
- Java的类进入内存,变成一份份Java字节码文件,每一份字节码文件就是Class类的实例对象(因为Class类就是描述这些字节码文件的类,是所有字节码文件的类)。
- 字节码文件就是把所有类的字节码文件抽取出的共性(属性、方法、各种信息)封装为一个统一的Class类,而每个字节码文件就是这个Class类的一个实例对象,所以这些对象可以调用Class类的方法,如getMehod(),isPrimitive(),getConstructor()等等。
- 反射把这些组成部分封装起来
- 组成部分的字节码文件: Field、Method、Contructor、Package等,这些字节码文件是Class类的实例对象,这些实例对象提供了一些方法暴露自己的信息。
-
疑问?
- 这些字节码文件与要反射的类有什么关系呢?
- 比如说String.class.getConstructor();这一句是String的字节码字节码文件(Class类的实例对象)使用了 Contructor字节码文件 (Class类的实例对象)的 getConstructor()方法?
- 牢记:
- 得到Class的三种方法:
String str1 = "abc";
//得到Class的三种方法:对象.getClass,类.class,Class.forName("类名")
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
三、Field的反射
-
ReflectPoint pt1 = new ReflectPoint(3,5);
//通过字节码,得到Field类对象
Field fieldY = pt1.getClass().getField("y");
System.out.println(fieldY.get(pt1));//
//得到private的字段
Field fieldX = pt1.getClass().getDeclaredField("x");//private�����ɼ�
fieldX.setAccessible(true);//private�������Է���
System.out.println(fieldY.get(pt1));
分享到:
相关推荐
黑马QT讲义,适合QT入门,使用,教程很比较基础,新手可以看看,另外视频链接在哔哩哔哩中。
黑马程序员-SpringCloud-学习笔记-03-Eureka注册中心
黑马程序员-SpringCloud-学习笔记01-认识微服务
黑马程序员 - Java基础教学 - 05 - 面向对象(1).doc
黑马程序员-SpringCloud-学习笔记-02-微服务拆分及远程调用
黑马程序员 - 毕向东 - Java基础教学 - 第02天 个人观看视频总结文档
day01_Object类、常用API day02_Collection、泛型 day03_List、Set、数据结构、Collections day04_Map,斗地主案例 day05_异常,线程 day06_线程、同步 day07_等待与唤醒案例、线程池、Lambda表达式 ...
黑马程序员-java32期培训视频(基础+就业)黑马程序员-java32期培训视频(基础+就业)
黑马程序员 - Java基础教学 - 04 - 数组、进制转换、二维数组
黑马程序员-梅兰商城项目实战,包含图片素材和编写源码。
黑马程序员 - 毕向东 - Java基础教学 - 第01天 个人观看视频总结文档
C++黑马程序员-演讲比赛流程管理系统记录
黑马程序员 - Java基础教学 - 08 - 面向对象(4)-多态.doc
黑马程序员 - Java基础教学 - 03 - 变量的作用域、for循环、break、continue、内存结构
NULL 博文链接:https://840198532-qq-com.iteye.com/blog/1491352
NULL 博文链接:https://840198532-qq-com.iteye.com/blog/1490901
黑马程序员--毕向东全套Java视屏,讲解的相当全面,各位如果需要,尽快下载哦! 另外如果视频链接存在打不开的问题,请留言,必定及时更新链接。
NULL 博文链接:https://840198532-qq-com.iteye.com/blog/1490903
黑马程序员 - Java基础教学 - 06 - 面向对象(2) - 关于静态static的那些事.doc
《Java 基础入门》课后习题答案 第 第 1 章 Java 开发入门 一、填空题 1、 Java EE、Java SE、Java ME 2、 JRE 3、 javac 4、 bin 5、 path、classpath 二、选择题 1、ABCD 2、C 3、D 4、B 5、B ...