diff --git a/README.md b/README.md index a210b374..f33e71a9 100644 --- a/README.md +++ b/README.md @@ -83,15 +83,15 @@ Github用户如果访问速度缓慢的话,可以转移到[码云](https://git **基础知识系统总结:** -* **[Java 基础知识回顾](docs/java/Java基础知识.md)** -* **[Java 基础知识疑难点/易错点](docs/java/Java疑难点.md)** -* **[一些重要的Java程序设计题](docs/java/Java程序设计题.md)** -* [J2EE 基础知识回顾](docs/java/J2EE基础知识.md) +1. **[Java 基础知识](docs/java/Java基础知识.md)** +2. **[Java 基础知识疑难点/易错点](docs/java/Java疑难点.md)** +3. [【加餐】一些重要的Java程序设计题](docs/java/Java程序设计题.md) +4. [【选看】J2EE 基础知识](docs/java/J2EE基础知识.md) **重要知识点详解:** -- [用好Java中的枚举,真的没有那么简单!](docs/java/basis/用好Java中的枚举真的没有那么简单.md) -- [Java 常见关键字总结:final、static、this、super!](docs/java/basis/final、static、this、super.md) +1. [枚举](docs/java/basis/用好Java中的枚举真的没有那么简单.md) (很重要的一个数据结构,用好枚举真的没有那么简单!) +2. [Java 常见关键字总结:final、static、this、super!](docs/java/basis/final、static、this、super.md) ### 容器 @@ -101,9 +101,7 @@ Github用户如果访问速度缓慢的话,可以转移到[码云](https://git **源码学习:** -* [ArrayList 源码学习](docs/java/collection/ArrayList.md) -* [LinkedList 源码学习](docs/java/collection/LinkedList.md) -* [HashMap(JDK1.8)源码学习](docs/java/collection/HashMap.md) +* [ArrayList 源码](docs/java/collection/ArrayList.md) 、[LinkedList 源码](docs/java/collection/LinkedList.md) 、[HashMap(JDK1.8)源码](docs/java/collection/HashMap.md) ### 并发 diff --git a/docs/java/Java基础知识.md b/docs/java/Java基础知识.md index 08484c18..a1ec9c78 100644 --- a/docs/java/Java基础知识.md +++ b/docs/java/Java基础知识.md @@ -548,6 +548,142 @@ Java Io 流共涉及 40 多个类,这些类看上去很杂乱,但实际上 ![deep and shallow copy](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/java-deep-and-shallow-copy.jpg) +## 38.什么是反射机制?反射机制的应用场景有哪些? + +### 反射机制介绍 + +JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。 + +### 获取Class对象的两种方式 + +如果我们动态获取到这些信息,我们需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。Java提供了两种方式获取Class对象: + +1.知道具体类的情况下可以使用: + +```java +Class alunbarClass = TargetObject.class; +``` + +但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象 + +2.通过 `Class.forName()`传入类的路径获取: + +```java +Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject"); +``` + +### 代码实例 + +**简单用代码演示一下反射的一些操作!** + +1.创建一个我们要使用反射操作的类 `TargetObject`: + +```java +package cn.javaguide; + +public class TargetObject { + private String value; + + public TargetObject() { + value = "JavaGuide"; + } + + public void publicMethod(String s) { + System.out.println("I love " + s); + } + + private void privateMethod() { + System.out.println("value is " + value); + } +} +``` + +2.使用反射操作这个类的方法以及参数 + +```java +package cn.javaguide; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class Main { + public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException { + /** + * 获取TargetObject类的Class对象并且创建TargetObject类实例 + */ + Class tagetClass = Class.forName("cn.javaguide.TargetObject"); + TargetObject targetObject = (TargetObject) tagetClass.newInstance(); + /** + * 获取所有类中所有定义的方法 + */ + Method[] methods = tagetClass.getDeclaredMethods(); + for (Method method : methods) { + System.out.println(method.getName()); + } + /** + * 获取指定方法并调用 + */ + Method publicMethod = tagetClass.getDeclaredMethod("publicMethod", + String.class); + + publicMethod.invoke(targetObject, "JavaGuide"); + /** + * 获取指定参数并对参数进行修改 + */ + Field field = tagetClass.getDeclaredField("value"); + //为了对类中的参数进行修改我们取消安全检查 + field.setAccessible(true); + field.set(targetObject, "JavaGuide"); + /** + * 调用 private 方法 + */ + Method privateMethod = tagetClass.getDeclaredMethod("privateMethod"); + //为了调用private方法我们取消安全检查 + privateMethod.setAccessible(true); + privateMethod.invoke(targetObject); + } +} + +``` + +输出内容: + +``` +publicMethod +privateMethod +I love JavaGuide +value is JavaGuide +``` + +### 静态编译和动态编译 + +- **静态编译:**在编译时确定类型,绑定对象 +- **动态编译:**运行时确定类型,绑定对象 + +### 反射机制优缺点 + +- **优点:** 运行期类型的判断,动态加载类,提高代码灵活度。 +- **缺点:** 1,性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的 java 代码要慢很多。2,安全问题,让我们可以动态操作改变类的属性同时也增加了类的安全隐患。 + +### 反射的应用场景 + +**反射是框架设计的灵魂。** + +在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。 + +举例: + +1. 我们在使用 JDBC 连接数据库时使用 `Class.forName()`通过反射加载数据库的驱动程序; +2. Spring 框架的IOC(动态加载管理Bean)创建对象以及AOP(动态代理)功能都和反射有联系; +4. 动态配置实例的属性; +5. ...... + +**推荐阅读:** + +- [Reflection:Java 反射机制的应用场景](https://segmentfault.com/a/1190000010162647?utm_source=tuicool&utm_medium=referral) +- [Java 基础之—反射(非常重要)](https://blog.csdn.net/sinat_38259539/article/details/71799078) + ## 参考 - https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jre