写在前面
今天继续讲Java中的类加载器和lambda表达式的知识!
类加载器和反射
类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三步来实现对这个类进行初始化。
-
加载
将.class
文件读入内存,并为之创建一个Class
对象。任何类被使用时系统都会建立一个Class
对象。 -
连接
- 验证:检查类的内部结构是否正确,并与其他类协调一致。
- 准备:为类的静态成员分配内存,并设置默认初始化值。
- 解析:将类的二进制数据中的符号引用替换为直接引用。
-
初始化
执行类的静态初始化器和静态代码块。
一个类的初始化时机
- 创建类的实例。
- 访问类的静态变量,或者为静态变量赋值。
- 调用类的静态方法。
- 使用反射方式强制创建某个类或接口对应的
java.lang.Class
对象。 - 初始化某个类的子类。
- 直接使用
java.exe
命令运行某个主类。
类加载器
负责将 .class
文件加载到内存中,并为之生成对应的 Class
对象。了解类加载机制可以帮助更好地理解程序的运行。
类加载器的组成
-
Bootstrap ClassLoader(根类加载器)
负责加载 Java 核心类,如System
、String
等。它在 JDK 的 JRElib
目录下的rt.jar
文件中。 -
Extension ClassLoader(扩展类加载器)
负责加载 JRE 扩展目录中的 JAR 包。在 JDK 的 JRElib
目录下的ext
目录中。 -
System ClassLoader(系统类加载器)
负责加载来自java
命令的.class
文件,以及classpath
环境变量所指定的 JAR 包和类路径。
Java 反射机制
Java 反射机制允许在运行时动态获取类的信息以及调用对象的方法。
通过反射获取构造方法并使用
-
获取构造方法
getConstructors()
getDeclaredConstructors()
-
创建对象
con.newInstance("zhangsan", 20);
通过反射获取成员变量并使用
-
获取所有成员
getFields()
getDeclaredFields()
-
获取单个成员
getField()
getDeclaredField()
-
修改成员的值
field.set(obj, value);
通过反射获取成员方法并使用
-
获取所有方法
getMethods()
getDeclaredMethods()
-
获取单个方法
getMethod()
getDeclaredMethod()
-
暴力访问
method.setAccessible(true);
Lambda 表达式
从 JDK 1.8 开始,Lambda 表达式简化了代码开发,支持函数式编程。
写 Lambda 表达式的场景
- 必须有相应的函数接口,函数接口是指内部有且仅有一个抽象方法的接口。
- 编译器通过类型推断机制可以推断出参数列表的类型。
Lambda 基本语法
Lambda 表达式由 ->
操作符分隔为两部分:
- 左侧:指定 Lambda 表达式需要的所有参数(对应接口中的形参)。
- 右侧:指定 Lambda 体,即要执行的功能(方法体)。
Lambda 表达式的分类
- 无参数,无返回值。
- 有一个参数,无返回值(若只有一个参数,小括号可以省略)。
- 有两个以上的参数,有返回值,并且 Lambda 体中有多条语句。
- 若 Lambda 体中只有一条语句,
return
和大括号都可以省略。 - Lambda 表达式的参数列表的数据类型可以省略,JVM 编译器通过上下文推断出数据类型。
Java 内置函数式接口
-
Predicate<T>
:断言型接口@FunctionalInterface public interface Predicate<T> { boolean test(T t); }
-
Function<T, R>
:函数型接口@FunctionalInterface public interface Function<T, R> { R apply(T t); }
-
Supplier<T>
:供给型接口@FunctionalInterface public interface Supplier<T> { T get(); }
-
Consumer<T>
:消费型接口@FunctionalInterface public interface Consumer<T> { void accept(T t); }
Lambda 用法再简洁之方法引用
-
对象的方法引用
对象引用::方法名
-
静态方法引用
类名::静态方法名
-
构造方法引用
类名::new
-
数组创建引用
元素类型[]::new
容易形成的误区
Lambda 表达式底层被封装成了主类的一个私有方法,并通过 invokedynamic
指令进行调用,简化了匿名内部类的写法。Lambda 表达式使代码更简洁,但也可能降低可读性。
优缺点
-
优点:
- 减少代码书写,减少匿名内部类的创建,节省内存占用。
- 使用时无需记忆接口和抽象函数。
-
缺点:
- 易读性较差,需要熟悉 Lambda 表达式和抽象函数中参数的类型。
- 不方便进行调试
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容