Java学习笔记 --- 反射机制
来源:互联网 发布:python做时间序列分析 编辑:程序博客网 时间:2024/05/18 02:14
做完了第一版的图书管理系统, 决定这段时间静下心好好看一看书, 一边复习Java基础和Servlet&JSP, 再一边学一学框架, 写读书笔记将学习到的知识点记录下来.
反射是什么?
反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。
这是百度里给出的概念, 可能大多数人跟我刚开始一样, 不是很理解这句话. 那么我们先从Java文件编译链接后生的可执行文件说起吧.
首先, 大家都明白, 一个.java文件经过编译链接会生成.class文件, 准确的来说, 应该是一个类经过编译会生成一个.class文件. 如果一个类里面除了主类还有其他类, 不管是内部类还是外部类, 每个类都会各自生成一个.class文件. 可能有人通过查看IDEA下classes目录会发现, 一个类经过编译链接后, 其内部类并不会生成独立的.class文件,但是实质上是会生成的, 只是IDEA下并没有显示出有这个.class文件而已, 我们在终端下来测试对比一下.
先来看一段Java代码:
public class test { public static void main(String[] args){ System.out.println("test"); } public class test1{ public void main(String[] args){ System.out.println("test1"); } }}class test2{ public static void main(String[] args){ System.out.println("test2"); }}
看一下它在IDEA下生成的.class文件
可以看到红色的目录下就是编译链接后生成的.class文件只有主类和外部类, 但事实上并非如此, 我们在终端下使用javac来编译一下试试看.
可以清楚地看到, 有三个.class文件, 内部类test1也被编译链接生成了一个.class文件.
分析这些的主要目的是想说, 每一个类都会生成对应的.class文件. 但是.class文件并不能直接运行在操作系统上, 它需要运行于JVM之上, 这也是为什么Java可以跨平台的原因. 那么Java的反射机制到底是什么呢? 简单点来讲, 就是反编译: .class -> .java. 也就是说, 我们可以通过反射机制, 从.class文件里去访问原来的.java文件里面类的属性方法, 甚至去创建新的对象.
在编程语言里, 有动态语言和静态语言之分, 动态语言是指程序在运行时可以改变其结构, 而静态语言不能. Java本身是属于静态语言, 它并不能在运行时改变程序的结构, 但是Java本身提供了反射机制, 这也使得Java具有了一丢丢动态语言的性质. 什么意思呢? 就是反射机制允许Java程序在运行时透过Reflection API取得任何一个已知名称的class的内部信息.
反射的功能和使用
好, 明白了反射是什么, 那我们来看看Java的反射机制都能干哪些事?
- 在运行时构造任意一个类的对象
- 在运行时创建新类对象
- 在运行时调用任一个对象的方法
- 在运行时判断任意一个对象所属的类
- 在运行时判断任意一个类所具有的成员变量和方法
在JDK中, 主要由以下类来实现Java反射机制, 这些类都位于java.lang.reflect包中.
Class类: 代表一个类
Field类: 代表一个类的成员变量(成员变量包括数据成员/方法成员/类成员等, 成员变量也称为类的属性)
Method类: 代表一个类的方法
Constructor类: 代表一个类的构造方法
Array类: 提供了动态创建数组, 以及访问数组的元素的静态方法
Proxy类和InvocationHandler接口: 提供了动态生成代理类以及实例的方法
那么下面我们来看一看如何使用反射.
1. 反射机制获取类
反射机制获取类有三种方法, 如下:
//第一种方式: Class c1 = Class.forName("Employee"); //第二种方式: //java中每个类型都有class 属性. Class c2 = Employee.class; //第三种方式: //java语言中任何一个java对象都有getClass 方法 Employee e = new Employee(); Class c3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
2. 创建对象
前面使用反射机制获取到了类, 那么现在就用获取到的类来创建对象.
//第一种方式Class c =Class.forName("Employee"); //第二种方式//创建此Class 对象所表示的类的一个新实例 Object o = c.newInstance(); //调用了Employee的无参数构造方法.
3. 获取属性
获取属性有获取所有属性和获取指定属性两种, 先来看一下获取所有属性.
//首先先获取整个类(以Integer这个类为例)Class c = Class.forName("java.lang.Integer");//然后获取该类的所有Field(属性)Field[] fs = c.getDeclaredFields();//定义字符串, 存储属性StringBuffer sb = new StringBuffer();//通过追加的方法,将每个属性拼接到此字符串中 //最外边的public定义 sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n"); //获取里边的每一个属性 for(Field field:fs){ sb.append("\t");//空格 sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等 sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字 sb.append(field.getName()+";\n");//属性的名字+回车 } sb.append("}"); System.out.println(sb);
下面是获取特定的属性.
我们通过传统方式和反射方式来对比看一下如何获取指定属性:
//传统方式:/* User u = new User(); u.age = 12; //set System.out.println(u.age); //get */ //反射方式//获取类 Class c = Class.forName("User"); //获取id属性 Field idF = c.getDeclaredField("id"); //实例化这个类赋给o Object o = c.newInstance(); //打破封装 idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。 //set//给o对象的id属性赋值"110" idF.set(o, "110"); //getSystem.out.println(idF.get(o));
4. 获取方法, 构造方法
这里关于获取方法和构造方法, 暂时先给出一张方法表, 具体细节等到下次再详细总结.
- Java反射机制学习笔记
- Java 反射机制-学习笔记
- Java反射机制学习笔记
- java反射机制学习笔记
- 【Java学习笔记】-----反射机制
- [学习笔记]Java反射机制
- Java反射机制学习笔记
- Java反射机制学习笔记
- java学习笔记反射机制
- java学习笔记-反射机制
- JAVA学习笔记--反射机制
- java反射机制学习笔记
- Java反射机制学习笔记
- Java反射机制学习笔记
- java反射机制学习笔记
- Java学习笔记 --- 反射机制
- Java 反射机制学习笔记
- 反射学习笔记:Java反射机制
- 1013. 数素数 (20)
- MaBatis框架
- 程序员笔试题之字符串(1)
- 递归实现打印12345---简单理解递归
- 提高Eclipse的速度,去掉对于工程的 Validatioan
- Java学习笔记 --- 反射机制
- Bootstrap Tree View从前端到后台的例子
- 零基础学习软件测试从懵逼到吊炸天之基础与进阶篇
- Pixy(Cmucam5)通过SPI与Arduino通信
- 记事本DEMO
- Android APK反编译之路
- Android使用Fiddler模拟弱网络环境测试
- Mac安装apache24和PHP多版本切换MongoDB和MYSQL
- 磁盘阵列(raid)