该文章Github地址:https://github.com/AntonyCheng/java-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】
在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!
上一章:由浅到深认识Java语言(52):JDK9新特性(改进JavaDocs&共存JAR)
54.JDK9新特性
集合不可变实例工厂方法
旧的创建不可变集合的方法
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CollectionFactoryMethodTester {
public static void main(String []args) {
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
set = Collections.unmodifiableSet(set);
System.out.println(set);
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list = Collections.unmodifiableList(list);
System.out.println(list);
Map<String, String> map = new HashMap<>();
map.put("A","Apple");
map.put("B","Boy");
map.put("C","Cat");
map = Collections.unmodifiableMap(map);
System.out.println(map);
}
}
运行结果如下:
[A, B, C]
[A, B, C]
{A=Apple, B=Boy, C=Cat}
创建可变集合很简单,但是创建不可变集合则先需要创建一个可变集合,然后再使用 Collections.unmodifiable{Map,Set,List}
创建不可变集合。
新的创建不可变集合的方法
在 Java 9 中,下面的方法以及它们的重载方法可用于创建各自集合的不可变实例:
1、创建不可变的列表(List);
static <E> List<E> of(E e1, E e2, E e3);
2、创建不可变的集合(Set);
static <E> Set<E> of(E e1, E e2, E e3);
3、创建不可变的哈希表(Hash);
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3);
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
其实就是添加给各个集合接口添加了 of() 方法 ,用于定义三种集合的不可变实例,而它们的参数,就是不可变实例的所有元素。
但是,这些方法还是有一些限制的
1、对于 List 和 Set 和 Map 三个接口的 of()
方法,重载方法的参数有0~10个不等;
2、对于 List 和 Set 和 of()
方法,有些重载还包含了一个参数 args 用于接受数量不定的值,这样就可以创建包含任意数量的List、Set;
3、如果要创建的不可变哈希(HashMap)的数量超过了10个,就不能再用of()方法了,而需要使用 ofEntries()
方法;
import java.util.*;
public class Demo {
public static void main(String[] args) {
Set<String> set = Set.of("A", "B", "C");
System.out.println(set);
List<String> list = List.of("A", "B", "C");
System.out.println(list);
Map<String, String> map = Map.of("A", "Apple", "B", "Boy", "C", "Cat");
System.out.println(map);
Map<String, String> map1 = Map.ofEntries(new AbstractMap.SimpleEntry<>("A", "Apple"), new AbstractMap.SimpleEntry<>("B", "Boy"), new AbstractMap.SimpleEntry<>("C", "Cat"));
System.out.println(map1);
}
}
运行结果如下:
[C, B, A]
[A, B, C]
{C=Cat, B=Boy, A=Apple}
{C=Cat, B=Boy, A=Apple}
接口的私有方法
Java8之前的接口
回忆一下,Java 8 之前的接口就只允许两种类型的数据,一个是常量、另一个就是公开 ( public ) 的抽象方法 ( abstract ),也就是说,Java 8 之前的版本不存在有着默认实现的方法。
接下来有一个示例代码:
public class InterfacePrivateMethodTester {
public static void main(String []args) {
LogOracle log = new LogOracle();
log.logInfo("");
log.logWarn("");
log.logError("");
log.logFatal("");
LogMySql log1 = new LogMySql();
log1.logInfo("");
log1.logWarn("");
log1.logError("");
log1.logFatal("");
}
}
final class LogOracle implements Logging {
@Override
public void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
@Override
public void logWarn(String message) {
getConnection();
System.out.println("Log Message : " + "WARN");
closeConnection();
}
@Override
public void logError(String message) {
getConnection();
System.out.println("Log Message : " + "ERROR");
closeConnection();
}
@Override
public void logFatal(String message) {
getConnection();
System.out.println("Log Message : " + "FATAL");
closeConnection();
}
@Override
public void getConnection() {
System.out.println("Open Database connection");
}
@Override
public void closeConnection() {
System.out.println("Close Database connection");
}
}
final class LogMySql implements Logging {
@Override
public void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
@Override
public void logWarn(String message) {
getConnection();
System.out.println("Log Message : " + "WARN");
closeConnection();
}
@Override
public void logError(String message) {
getConnection();
System.out.println("Log Message : " + "ERROR");
closeConnection();
}
@Override
public void logFatal(String message) {
getConnection();
System.out.println("Log Message : " + "FATAL");
closeConnection();
}
@Override
public void getConnection() {
System.out.println("Open Database connection");
}
@Override
public void closeConnection() {
System.out.println("Close Database connection");
}
}
interface Logging {
String ORACLE = "Oracle_Database";
String MYSQL = "MySql_Database";
void logInfo(String message);
void logWarn(String message);
void logError(String message);
void logFatal(String message);
void getConnection();
void closeConnection();
}
运行结果如下:
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Java8的接口
Java 8 也终于作出了一些改变,Java 8 中的接口,可以具有以下类型的变量和方法:
1、常量;
2、虚方法;
3、默认方法;
4、静态方法;
将上面的范例改一改,使用 Java 8 的特性:
public class InterfacePrivateMethodTester {
public static void main(String []args) {
LogOracle log = new LogOracle();
log.logInfo("");
log.logWarn("");
log.logError("");
log.logFatal("");
LogMySql log1 = new LogMySql();
log1.logInfo("");
log1.logWarn("");
log1.logError("");
log1.logFatal("");
}
}
final class LogOracle implements Logging {}
final class LogMySql implements Logging {}
interface Logging {
String ORACLE = "Oracle_Database";
String MYSQL = "MySql_Database";
default void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
default void logWarn(String message) {
getConnection();
System.out.println("Log Message : " + "WARN");
closeConnection();
}
default void logError(String message) {
getConnection();
System.out.println("Log Message : " + "ERROR");
closeConnection();
}
default void logFatal(String message) {
getConnection();
System.out.println("Log Message : " + "FATAL");
closeConnection();
}
static void getConnection() {
System.out.println("Open Database connection");
}
static void closeConnection() {
System.out.println("Close Database connection");
}
}
运行结果如下:
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Java 8 的接口中的方法可以有默认实现,也就是使用 default 关键字修饰的方法,所以,类实现某个接口就比较简单了,可以有选择性的实现部分方法。
但是仍然有坑,就是每个默认方法中的代码,都必须完整的,而且不能调用其它的默认实现方法。
Java9的接口
Java 9 中可以为接口提供私有的方法,包括私有成员方法和私有静态方法
所以Java 9 中的接口,可以具有以下类型的变量和方法
1、 常量;
2、 虚方法;
3、 默认方法;
4、 静态方法;
5、 私有静态方法;
6、 私有方法;
于是可以继续修改刚刚的例子,让其更简单明白些:
public class InterfacePrivateMethodTester {
public static void main(String []args) {
LogOracle log = new LogOracle();
log.logInfo("");
log.logWarn("");
log.logError("");
log.logFatal("");
LogMySql log1 = new LogMySql();
log1.logInfo("");
log1.logWarn("");
log1.logError("");
log1.logFatal("");
}
}
final class LogOracle implements Logging {}
final class LogMySql implements Logging {}
interface Logging {
String ORACLE = "Oracle_Database";
String MYSQL = "MySql_Database";
private void log(String message, String prefix) {
getConnection();
System.out.println("Log Message : " + prefix);
closeConnection();
}
default void logInfo(String message) {
log(message, "INFO");
}
default void logWarn(String message) {
log(message, "WARN");
}
default void logError(String message) {
log(message, "ERROR");
}
default void logFatal(String message) {
log(message, "FATAL");
}
private static void getConnection() {
System.out.println("Open Database connection");
}
private static void closeConnection() {
System.out.println("Close Database connection");
}
}
运行结果如下:
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection