предисловие
Выпущен JDK 15~ Давайте рассмотрим новые функции JDK 5-15, давайте учиться вместе~
Эта статья была включена в github
Общественный номер: маленький мальчик собирает улиток
Что нового в Java 5
1. Дженерики
Обобщения — это, по сути, параметризованные типы, которые решают проблему неопределенности конкретных типов объектов.
List<String> strList=new ArrayList<String>();
2. Расширенный цикл (для каждого)
Цикл for-each упрощает обход коллекции.
String [] str = {"关注","公众号","捡田螺的小男孩"};
for (String temp:str) {
System.out.println(temp);
}
3. Автоматическая упаковка и распаковка
- Autoboxing: автоматическое преобразование базовых типов данных в соответствующие классы-оболочки.
- Автоматическая распаковка: это автоматическое преобразование класса-оболочки в соответствующий базовый тип данных.
Типы упаковки: целое, двойное, с плавающей запятой, длинное, короткое, символьное и логическое.
Integer i =666; //自动装箱
int a= i; //自动拆箱
4. Перечисление
Ключевое слово enum создает из ограниченного набора именованных значений новый тип, который можно использовать как обычные компоненты программы — это тип перечисления.
enum SeasonEnum {
SPRING,SUMMER,FALL,WINTER;
}
5. Переменные параметры
Когда мы определяем параметры метода, мы не уверены, сколько их нужно определить, поэтому мы можем определить их какпеременный параметр, что по сути являетсямножество.
public static void main(String[] args) throws Exception {
String [] str = {"关注","公众号","捡田螺的小男孩"};
testVarargs(str);
String str1 = "关注公众号,捡田螺的小男孩";
testVarargs(str1);
}
//可变参数String... args
private static void testVarargs(String... args) {
for (String arg : args) {
System.out.println(arg);
}
}
6. Примечания
Аннотации можно понимать как специальные теги в коде, эти теги можно читать во время компиляции, загрузки класса, во время выполнения и выполнять соответствующую обработку.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
7. Статический импорт
Импортируя статический класс, вы можете использовать статические переменные или методы в классе. Взгляните на пример~
import static java.lang.System.out; //静态导入System类的静态变量out
public class Test {
public static void main(String[] args) throws Exception {
String str1 = "关注公众号,捡田螺的小男孩";
System.out.println(str1); //常规写法
out.println(str1); //静态导入,可以直接使用out输出
}
}
8. Библиотека параллелизма потоков (JUC)
JDK5 расширяет возможности обработки потоков Пакет java.util.concurrent предоставляет следующие классы и интерфейсы:
- Пул потоков: интерфейс ExecutorService
- Отражение потока: класс блокировки
- Связь с потоком: интерфейс условий
- Синхронизированная очередь: класс ArrayBlockingQueue
- Синхронизированная коллекция: класс ConcurrentHashMap
Что нового в Java 6
1. Класс Desktop и класс SystemTray
JDK 6 добавляет два новых класса в пакет java.awt: класс Desktop и класс SystemTray.
- Класс рабочего стола: используется для открытия системного браузера по умолчанию для просмотра указанного URL-адреса, открытия системного почтового клиента по умолчанию для отправки почты и т. д.
- Класс SystemTray: используется для создания программы панели задач в области панели задач, если в Microsoft Windows она называется областью состояния «панели задач».
//获取Desktop实例
Desktop desktop = Desktop.getDesktop();
desktop.browse(URI.create("https://www.baidu.com"));
2. Используйте JAXB2 для реализации сопоставления между объектами и XML.
JAXB, архитектура Java для привязки XML, может реализовать сопоставление между объектами и XML.Обычно используемые аннотации:
- @XmlRootElement: аннотированный класс, соответствующий корневому элементу xml, использует атрибут name для определения имени корневого узла.
- @XmlElement: укажите поле или метод получения/установки для сопоставления с узлом xml, используйте атрибут имени, чтобы определить имя корневого узла.
- @XmlAttribute: сопоставьте атрибуты объекта JavaBean с атрибутами xml и используйте атрибут имени, чтобы указать псевдоним для сгенерированного атрибута xml.
- @XmlAccessorType: определяет, какой тип сопоставления этого класса необходимо сопоставить с xml.
- @XmlSchema: сопоставляет пакеты с пространствами имен XML.
Давайте посмотрим пример~
public class JAXB2XmlTest {
public static void main(String[] args) throws JAXBException, IOException {
List<Singer> list = new ArrayList<>();
list.add(new Singer("jay", 8));
list.add(new Singer("eason", 10));
SingerList singerList = new SingerList();
singerList.setSingers(list);
String str = JAXB2XmlTest.beanToXml(singerList, SingerList.class);
String path = "C:\\jay.txt";
BufferedWriter bfw = new BufferedWriter(new FileWriter(new File(path)));
bfw.write(str);
bfw.close();
}
private static String beanToXml(Object obj, Class<?> load) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(load);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
StringWriter writer = new StringWriter();
marshaller.marshal(obj,writer);
return writer.toString();
}
}
public class Singer {
private String name;
private int age;
public Singer(String name, int age) {
this.name = name;
this.age = age;
}
@XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlAttribute(name="age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@XmlRootElement(name="list")
public class SingerList {
private List<Singer> singers;
@XmlElement(name="singer")
public List<Singer> getSingers() {
return singers;
}
public void setSingers(List<Singer> singers) {
this.singers = singers;
}
}
текущий результат:
<?xml version="1.0" encoding="GBK" standalone="yes"?>
<list>
<singer age="8" name="jay"/>
<singer age="10" name="eason"/>
</list>
3. Облегченный API Http-сервера
JDK 6 предоставляет простой API-интерфейс Http-сервера, который может создавать встроенный Http-сервер и поддерживает протоколы Http и Https. HttpServer вызовет метод обратного вызова класса реализации HttpHandler для обработки клиентского запроса, здесь пользователю нужно только реализовать интерфейс HttpHandler.
/**
* 根据Java提供的API实现Http服务器
*/
public class MyHttpServer {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//创建HttpServer服务器
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 10);
//将 /jay请求交给MyHandler处理器处理
httpServer.createContext("/", new MyHandler());
httpServer.start();
}
}
public class MyHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) throws IOException {
//请求头
Headers headers = httpExchange.getRequestHeaders();
Set<Map.Entry<String, List<String>>> entries = headers.entrySet();
StringBuffer response = new StringBuffer();
for (Map.Entry<String, List<String>> entry : entries){
response.append(entry.toString() + "\n");
}
//设置响应头属性及响应信息的长度
httpExchange.sendResponseHeaders(200, response.length());
//获得输出流
OutputStream os = httpExchange.getResponseBody();
os.write(response.toString().getBytes());
os.close();
}
}
4. Плагин API обработки аннотаций
JDK 6 предоставляет подключаемый API обработки аннотаций, который позволяет определяемым нами аннотациям вступать в силу во время компиляции, а не во время выполнения, чтобы байт-код можно было изменять во время компиляции. С помощью этой функции реализован фреймворк lombok.Lombok автоматически генерирует конструкторы, геттеры/сеттеры, equals, hashcode, toString и другие методы для свойств во время компиляции с помощью аннотаций, что значительно упрощает разработку кода.
5. STAX
STAX — это API для обработки XML-документов в JDK6.
public class STAXTest {
public static void main(String[] args) throws Exception {
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream("C:\\jay.xml"));
XMLEvent event = null;
StringBuffer stringBuffer = new StringBuffer();
while (xmlEventReader.hasNext()) {
event = xmlEventReader.nextEvent();
stringBuffer.append(event.toString());
}
System.out.println("xml文档解析结果:");
System.out.println(stringBuffer);
}
}
результат операции:
xml文档解析结果:
<?xml version="1.0" encoding='GBK' standalone='yes'?><list>
<singer name='jay' age='8'></singer>
<singer name='eason' age='10'></singer>
</list>ENDDOCUMENT
6. Common Annotations
Общие аннотации изначально были частью спецификации Java EE 5.0 (JSR 244), а теперь Sun включила их часть в Java SE 6.0. С добавлением функциональности метаданных аннотаций в Java SE 5.0 многие технологии Java будут использовать разделы аннотаций вместо файлов XML для настройки параметров запуска.
Ниже перечислены несколько аннотаций в Common Annotations 1.0:
- @Generated: используется для аннотирования сгенерированного исходного кода.
- @Resource: он используется для пометки ресурсов, от которых он зависит, и контейнер соответствующим образом внедряет зависимости внешних ресурсов.Существует два метода: внедрение на основе поля и внедрение на основе метода установки.
- @Resources: отметьте несколько внешних зависимостей одновременно, контейнер внедрит все эти внешние зависимости.
- @PostConstruct: аннотируйте метод, который запускается после внедрения контейнером всех зависимостей для инициализации после внедрения зависимостей.Только один метод может быть помечен как PostConstruct.
- @PreDestroy: когда экземпляр объекта собирается удалить из контейнера, выполняемый метод обратного вызова должен быть помечен как PreDestroy.
7. Compiler API
Компилятор javac может компилировать исходные файлы .java в файлы .class, а новая функция JDK 6, Compiler API (JSR 199), также может динамически компилировать исходные файлы Java.
public class CompilerApiTest {
public static void main(String[] args) throws Exception {
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager standardJavaFileManager = javaCompiler.getStandardFileManager(null,null,null);
Iterable<? extends JavaFileObject> javaFileObjects = standardJavaFileManager.getJavaFileObjects("C:\\Singer.java");
javaCompiler.getTask(null, standardJavaFileManager, null, null, null, javaFileObjects).call();
standardJavaFileManager.close();
}
}
Результат выполнения: файл Singer.class будет сгенерирован в каталоге C.
8. Поддержка языков сценариев (например: ruby, groovy, javascript)
JDK6 добавляет поддержку языков сценариев (JSR 223).Принцип заключается в компиляции языков сценариев в байт-коды, чтобы языки сценариев также могли пользоваться многими преимуществами платформы Java, включая переносимость и безопасность. Реализация JDK6 включает в себя механизм языка сценариев на основе Mozilla Rhino, поэтому он может поддерживать javascript, конечно, JDK также поддерживает другие языки, такие как ruby
public class JavaScriptTest {
public static void main(String[] args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
String script;
try {
script = "print('Hello')";
engine.eval(script);// 执行脚本
}catch (Exception e) {
e.printStackTrace();
}
}
}
//output
Hello
Что нового в Java 7
1.switch поддерживает тип строки String.
String singer = "jay";
switch (singer) {
case "jay" :
System.out.println("周杰伦");
break;
case "eason" :
System.out.println("陈奕迅");
break ;
default :
System.out.println("其他");
break ;
}
2. попробуйте с ресурсами, ресурсы автоматически закрываются
До JDK 7:
BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt"));
try {
return br.readLine();
} finally {
br.close();
}
После JDK 7:
/*
* 声明在try括号中的对象称为资源,在方法执行完毕后会被自动关闭
*/
try (BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt")) {
return br.readLine();
}
3. Целочисленные типы, такие как (byte, short, int, long), могут быть представлены в двоичном формате.
//0b或者0B表示二进制
int a = 0b010;
int b = 0B010;
4. Числовые константы поддерживают подчеркивание
int a = 11_11;//a的值为1111,下划线不影响实际值,提升可读性
5. Общий тип экземпляра выводится автоматически, т.е. ""
До JDK 7:
Map<String, List<String>> map = new HashMap<String, List<String>>();
После JDK 7:
//不须声明类型,自动根据前面<>推断其类型
Map<String, List<String>> map = new HashMap<>();
6. Захватывайте несколько типов исключений в одном перехвате, разделяя их (|)
До JDK 7
try{
//do something
} catch (FirstException e) {
logger.error(e);
} catch (SecondException e) {
logger.error(ex);
}
После JDk 7
try{
//do something
} catch (FirstException | SecondException e) {
logger.error(e);
}
7. Усовершенствованная файловая система
Java7 предоставляет новый API NIO2.0 для облегчения кодирования управления файлами. Например, в пакете java.nio.file можно использовать общие типы, такие как Path, Paths, Files и WatchService.
Path path = Paths.get("C:\\jay\\七里香.txt"); //创建Path对象
byte[] bytes= Files.readAllBytes(path); //读取文件
System.out.println(path.getFileName()); //获取当前文件名称
System.out.println(path.toAbsolutePath()); // 获取文件绝对路径
System.out.println(new String(bytes, "utf-8"));
8. Структура разветвления/соединения
Платформа, предоставляемая Java7 для параллельного выполнения задач, представляет собой структуру, которая делит большую задачу на несколько небольших задач и, наконец, суммирует результаты каждой маленькой задачи для получения результатов большой задачи.
Fork/join вычисляет 1-1000 кумулятивное значение:
public class ForkJoinPoolTest {
private static final Integer DURATION_VALUE = 100;
static class ForkJoinSubTask extends RecursiveTask<Integer>{
// 子任务开始计算的值
private Integer startValue;
// 子任务结束计算的值
private Integer endValue;
private ForkJoinSubTask(Integer startValue , Integer endValue) {
this.startValue = startValue;
this.endValue = endValue;
}
@Override
protected Integer compute() {
//小于一定值DURATION,才开始计算
if(endValue - startValue < DURATION_VALUE) {
System.out.println("执行子任务计算:开始值 = " + startValue + ";结束值 = " + endValue);
Integer totalValue = 0;
for (int index = this.startValue; index <= this.endValue; index++) {
totalValue += index;
}
return totalValue;
} else {
// 将任务拆分,拆分成两个任务
ForkJoinSubTask subTask1 = new ForkJoinSubTask(startValue, (startValue + endValue) / 2);
subTask1.fork();
ForkJoinSubTask subTask2 = new ForkJoinSubTask((startValue + endValue) / 2 + 1 , endValue);
subTask2.fork();
return subTask1.join() + subTask2.join();
}
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// Fork/Join框架的线程池
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Integer> taskFuture = pool.submit(new ForkJoinSubTask(1,1000));
Integer result = taskFuture.get();
System.out.println("累加结果是:" + result);
}
}
результат операции:
...
执行子任务计算:开始值 = 189;结束值 = 250
执行子任务计算:开始值 = 251;结束值 = 313
执行子任务计算:开始值 = 314;结束值 = 375
执行子任务计算:开始值 = 376;结束值 = 438
执行子任务计算:开始值 = 439;结束值 = 500
执行子任务计算:开始值 = 501;结束值 = 563
执行子任务计算:开始值 = 564;结束值 = 625
执行子任务计算:开始值 = 626;结束值 = 688
执行子任务计算:开始值 = 689;结束值 = 750
执行子任务计算:开始值 = 751;结束值 = 813
执行子任务计算:开始值 = 814;结束值 = 875
执行子任务计算:开始值 = 876;结束值 = 938
执行子任务计算:开始值 = 939;结束值 = 1000
累加结果是:500500
Что нового в Java 8
1. лямбда-выражения
Lambda позволяет передавать функции в методы в качестве параметров метода.
Формат синтаксиса:
(parameters) -> expression 或 (parameters) ->{ statements; }
Пример кода:
Arrays.asList("jay", "Eason", "SHE").forEach(
( String singer ) -> System.out.print( singer + ",") );
2. Функциональный интерфейс
Разработчики Lambda разработали функциональные интерфейсы, чтобы сделать существующие функции совместимыми с выражениями Lambda.
- Функциональный интерфейс — это интерфейс только с одной функцией, которую можно неявно преобразовать в лямбда-выражение.
- Java 8 предоставляет аннотацию @FunctionalInterface для явного объявления функционального интерфейса.
- java.lang.Runnable и java.util.concurrent.Callable — примеры функциональных интерфейсов~
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
3. Ссылка на метод
Ссылки на методы предоставляют очень полезный синтаксис для прямых ссылок на методы или конструкторы существующих классов или объектов (экземпляров) Java. Он работает с лямбда-выражениями, чтобы уменьшить избыточный код и сделать код более кратким.
//利用函数式接口Consumer的accept方法实现打印,Lambda表达式如下
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("jay");
//引用PrintStream类(也就是System.out的类型)的println方法,这就是方法引用
consumer = System.out::println;
consumer.accept("关注公众号捡田螺的小男孩");
4. Метод по умолчанию
Метод по умолчанию — это метод, который имеет реализацию в интерфейсе. Он позволяет добавлять в интерфейс новые методы, но не требует, чтобы классы, реализующие интерфейс, реализовывали новые методы.
public interface ISingerService {
// 默认方法
default void sing(){
System.out.println("唱歌");
}
void writeSong();
}
//JaySingerServiceImpl 不用强制实现ISingerService的默认sing()方法
public class JaySingerServiceImpl implements ISingerService {
@Override
public void writeSong() {
System.out.println("写了一首七里香");
}
}
5.Stream API
Stream API, который поддерживает функциональные операции с потоками элементов, интегрирован в API коллекций и может выполнять пакетные операции с коллекциями. Общие API:
- фильтр фильтр
- карта потока карта
- сокращение объединяет элементы в потоке
- collect возвращает коллекцию
- сортированная сортировка
- Преобразование потока flatMap
- limit возвращает указанное количество потоков
- отличительный удаляет повторяющиеся элементы
public class Singer {
private String name;
private Integer songNum;
private Integer age;
...
}
List<Singer> singerList = new ArrayList<Singer>();
singerList.add(new Singer("jay", 11, 36));
singerList.add(new Singer("eason", 8, 31));
singerList.add(new Singer("JJ", 6, 29));
List<String> singerNameList = singerList.stream()
.filter(singer -> singer.getAge() > 30) //筛选年龄大于30
.sorted(Comparator.comparing(Singer::getSongNum)) //根据歌曲数量排序
.map(Singer::getName) //提取歌手名字
.collect(Collectors.toList()); //转换为List
6. Optional
В Java 8 появился дополнительный класс для разрешения NullPointerException. Необязательный заменяет if...else, чтобы решить проблему нулевого указателя и сделать код более кратким.
если... еще пусто
Singer singer = getSingerById("666");
if (singer != null) {
String name = singer.getName();
System.out.println(name);
}
Необязательное обнуление
Optional<Singer> singer = Optional.ofNullable(getSingerById("666"));
singer.ifPresent(s -> System.out.println(s.getName()));
7. Date Time API
Обработка API даты до JDK 8 имеет такие проблемы, как безопасность без потоков и проблематичная обработка часового пояса. Java 8 предоставляет новый API для работы с датами в пакете java.time, который упрощает обработку дат~
LocalDate today = LocalDate.now();
int year = today.getYear();
System.out.println("今年是" + year);
//是否闰年
System.out.println("今年是不是闰年:" + today.isLeapYear());
LocalDateTime todayTime = LocalDateTime.now();
System.out.println("当前时间" + todayTime);
//时区指定
System.out.println("美国时间:" + ZonedDateTime.of(todayTime,ZoneId.of("America/Los_Angeles")));
LocalDate specailDate = LocalDate.of(2020, 6, 20);
LocalDate expectDate = specailDate.plus(100, ChronoUnit.DAYS);
System.out.println("比较特别的一天" + specailDate);
System.out.println("特殊日期的100天" + expectDate);
8. Повторите комментарии
Повторяющиеся аннотации, то есть аннотация может использоваться несколько раз в классе, свойстве или методе одновременно; используйте @Repeatable для определения повторяющихся аннотаций.
@Repeatable(ScheduleTimes.class)
public @interface ScheduleTime {
String value();
}
public @interface ScheduleTimes {
ScheduleTime[] value();
}
public class ScheduleTimeTask {
@ScheduleTime("10")
@ScheduleTime("12")
public void doSomething() { }
}
9. Base64
Java 8 добавляет поддержку кодировки Base64 в официальную библиотеку~
String str = "公众号:捡田螺的小男孩";
String encoded = Base64.getEncoder().encodeToString(str.getBytes( StandardCharsets.UTF_8));
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
10. Новые возможности JVM
Используйте метапространство Metaspace вместо пространства PermGen, параметры JVM используют -XX:MetaSpaceSize и -XX:MaxMetaspaceSize для установки размера.
Что нового в Java 9
1. система модулей Java
Что такое модульность?
Крупномасштабная система, такая как веб-сайт торгового центра, будет содержать множество модулей, таких как: модуль заказа, модуль информации о пользователе, модуль информации о продукте, модуль рекламного места и так далее. Каждый модуль будет вызывать друг друга. Производительность очень неэффективна, если каждый модуль работает независимо и управляет всеми другими модулями. Однако, если модуль запущен, будут запущены только модули, от которых он зависит, и производительность будет значительно повышена. В этом и заключается идея модульности JDK 9.
Что такое модульность JDK 9?
Модульная система платформы Java, или Project Jigsaw, привносит методы модульной разработки на платформу Java. После введения модульной системы JDK был реорганизован в 94 модуля. Приложения Java могут использовать новый инструмент jlink для создания пользовательского образа среды выполнения, который содержит только зависимые модули JDK. Это может значительно уменьшить размер среды выполнения Java.
Важные особенности модулей Java 9:
- В корневой каталог его артефакта включен файл module-info.class, описывающий модуль.
- Формат артефакта может быть традиционным файлом JAR или файлом JMOD, который является новым в Java 9.
- Этот файл скомпилирован из файла исходного кода module-info.java в корневом каталоге.
- Файл объявления модуля может описывать различные характеристики модуля.
В файле module-info.java мы можем объявить модуль с новым ключевым словом module, как показано ниже. Самое простое объявление модуля для модуля com.mycompany.mymodule приведено ниже.
module com.jay.sample { //关键词module来声明一个模块
exports com.jay.sample; //使用 exports可以声明模块对其他模块所导出的包。
requires com.jay.common; //使用requires可以声明模块对其他模块的依赖关系。
}
2. Неизменяемые методы фабрики коллекций
Для создания неизменяемых коллекций до JDK9:
List<String> stringList = new ArrayList<>();
stringList.add("关注公众号:");
stringList.add("捡田螺的小男孩");
List<String> unmodifiableList = Collections.unmodifiableList(stringList);
JDK 9 предоставляет фабричные методы, такие как List.of(), Set.of(), Map.of() и Map.ofEntries() для создания неизменяемых коллекций:
List<String> unmodifiableList = List.of("关注公众号:","捡田螺的小男孩");
3. Интерфейс поддерживает приватные методы
JDK 8 поддерживает реализацию методов по умолчанию и статических методов в интерфейсах, но не может создавать частные методы в интерфейсах.Чтобы избежать избыточности кода и улучшить читабельность, JDK 9 поддерживает частные методы в интерфейсах.
public interface IPrivateInterfaceTest {
//JDK 7 之前
String a = "jay";
void method7();
//JDK 8
default void methodDefault8(){
System.out.println("JDK 8新特性默认方法");
}
static void methodStatic8() {
System.out.println("JDk 8新特性静态方法");
}
//Java 9 接口支持私有方法
private void method9(){}
}
4. Обновление оператора Diamond
- Алмазный оператор был введен в Java 7, чтобы сделать код более читаемым, но его нельзя использовать для анонимных внутренних классов.
- В Java 9 его можно использовать с анонимными внутренними классами для улучшения читабельности кода.
//JDK 5,6
Map<String, String> map56 = new HashMap<String,String>();
//JDk 7,8
Map<String, String> map78 = new HashMap<>();
//JDK 9 结合匿名内部类的实现
Map<String, String> map9 = new HashMap<>(){};
5. Необязательные улучшения класса
В java 9 java.util.Optional добавляет много новых полезных методов, таких как:
- stream()
- ifPresentOrElse()
- or()
Улучшение метода ifPresentOrElse заключается в наличии else, который принимает два параметра Consumer и Runnable.
import java.util.Optional;
public class OptionalTest {
public static void main(String[] args) {
Optional<Integer> optional = Optional.of(1);
optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->
System.out.println("Not Present."));
optional = Optional.empty();
optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->
System.out.println("Not Present."));
}
}
6. Пакет Jar, совместимый с несколькими версиями
Многие компании используют старые версии JDK, JDK6, JDk5 и даже JDk4, и дело не в том, что они не хотят обновлять версию JDk, а в том, что их беспокоят проблемы совместимости. Новая функция JDK 9, пакет Jar, совместимый с несколькими версиями, решает эту проблему. Например: Предположим, вы использовали Xiaomi Mi 8, и вы очень привыкли к процессу его работы.Внезапно выходит Xiaomi Mi 9. Несмотря на то, что многие новые функции Xiaomi Mi 9 завораживают, некоторые люди не будут покупать Xiaomi Mi 9. легко, потому что они уже привыкли к процессу Xiaomi Mi 9. 8. Точно так же, почему многие компании не обновляют JDK, здесь. Тем не менее, эта функция JDK 9 очень мощная, она может обновить вашу версию до JDK 9, но это все еще работающий процесс старой версии, то есть наследование новых функций в старом работающем процессе~
7. Инструменты JShell
Инструмент jShell эквивалентен инструменту cmd.Тогда вы можете запускать методы Java, операторы Java и т. д. непосредственно на нем, как и с инструментом cmd~
jshell> System.out.println("关注公众号:捡田螺的小男孩");
关注公众号:捡田螺的小男孩
8. Улучшения в попытке использования ресурсов
JDK 9 обновил механизм обработки исключений try-with-resources~
//JDK 7,8
try (BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt")) {
br.readLine();
}catch(IOException e){
log.error("IO 异常,e:{}",e);
}
//JDk 9
BufferedReader br = new BufferedReader(new FileReader("d:七里香.txt")
try(br){
br.readLine();
}catch(IOException e){
log.error("IO 异常,e:{}",e);
}
9. Улучшения потокового API
JDK 9 расширяет операции потоковой обработки, добавляя в Stream API следующие методы:
- взять пока()
- dropWhile()
- iterate
- ofNullable
takeWhile
Принимает предикат (интерфейс Predicate) в качестве параметра, возвращает подмножество данного Stream до тех пор, пока в первый раз оператор предиката не вернет false
// 语法格式
default Stream<T> takeWhile(Predicate<? super T> predicate)
//代码示例
Stream.of(1,2,3).takeWhile(s-> x<2)
.forEach(System.out::println);
//输出
1
dropWhile
В отличие от takeWhile(), использует предикат (интерфейс предиката) в качестве параметра до тех пор, пока оператор предиката не вернет значение true в первый раз, возвращая подмножество данного потока.
//语法
default Stream<T> dropWhile(Predicate<? super T> predicate)
//代码示例
Stream.of(1,2,3).dropWhile(s-> x<2)
.forEach(System.out::println);
//输出
2
3
iterate
Метод iterate() может возвращать поток элементов, начиная с seed (первый параметр), сопоставлять Predicate (второй параметр) до тех пор, пока он не вернет false, и использовать третий параметр для создания следующего элемента.
//语法
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
//代码示例
IntStream.iterate(2, x -> x < 10, x -> x*x).forEach(System.out::println);
//输出
2
4
ofNullable
Получает элемент и создает один поток элементов, если указанный элемент не равен NULL, возвращает пустой поток, если элемент имеет значение NULL.
//语法
static <T> Stream<T> ofNullable(T t)
//代码示例
Stream<Integer> s1= Stream.ofNullable(100);
s1.forEach(System.out::println)
Stream<Integer> s2 = Stream.ofNullable(null);
s2.forEach(System.out::println)
//输出
100
10. Другие
- Клиент HTTP 2 (поддерживает потоковую передачу WebSocket и HTTP2 и отправку сервера)
- Process API (для контроля и управления процессами операционной системы)
- Строковое изменение базовой структуры хранения (char[] заменено на byte[])
- Ограничения на добавление идентификатора (String_="hello" использовать нельзя)
- Reactive Streaming API (поддерживает реактивное программирование в Java 9)
Что нового в Java 10
1. Вывод типа локальной переменной
JDK 10 добавляет функцию определения типа локальной переменной, которая позволяет Java автоматически определять типы данных, такие как var в Js. var в Java — это зарезервированное имя типа, а не ключевое слово.
До JDK 10
List<String> list = new ArrayList<String>();
Stream<Integer> stream = Stream.of(1, 2, 3);
После JDK 10
var list = new ArrayList<String>(); // ArrayList<String>
var stream = Stream.of(1, 2, 3);
Использование вывода типа переменной var также имеет ограничения, толькоограниченноев следующих сценариях:
- локальные переменные с инициализаторами
- Индексная переменная в расширенном цикле for
- Локальные переменные, объявленные в традиционных циклах for
а такженельзя использовать для
- Вывод типов параметров метода
- Вывод типа параметра конструктора
- Выведите тип возвращаемого значения метода
- вывод типа поля
- выражение захвата
2. Усовершенствования неизменяемых коллекций
В JDK 10 List, Set, Map предоставляют новый статический метод copyOf(Collection extends E> coll), который возвращает неизменяемую копию коллекции Collection.
Исходный код JDK:
static <E> List<E> copyOf(Collection<? extends E> coll) {
return ImmutableCollections.listCopy(coll);
}
Пример использования:
var oldList = new ArrayList<String>();
oldList.add("欢迎关注公众号:");
oldList.add("捡田螺的小男孩");
var copyList = List.copyOf(oldList);
oldList.add("在看、转载、点赞三连");
copyList.add("双击666"); //UnsupportedOperationException异常
3. Параллельный полный сборщик мусора G1
JDK 9 представляет G1 в качестве сборщика мусора по умолчанию и использует однопоточный алгоритм сжатия на основе маркировки-очистки-уплотнения при выполнении GC. Чтобы свести к минимуму влияние зависаний приложений, вызванных полным сборщиком мусора, в Java 10 будет введен многопоточный параллельный сборщик мусора для G1, при этом будет использоваться то же количество параллельных рабочих потоков, что и для коллекций молодого поколения и смешанных коллекций, что сократит количество полных сборщиков мусора. , чтобы улучшить производительность и увеличить пропускную способность.
4. Локальное рукопожатие потока
Управление потоком в Java 10 вводит концепцию точки сохранения JVM, которая позволит реализовать обратные вызовы потока без запуска глобальной точки сохранения JVM, выполняемой самим потоком или потоком JVM, сохраняя при этом поток в заблокированном состоянии, что будет удобно make Можно останавливать отдельные потоки или не останавливать потоки.
5. Необязательно добавляет метод orElseThrow()
Необязательный, необязательныйDouble и другие классы добавляют новый метод orElseThrow(), который создает исключение при отсутствии значения.
6. Другие новые функции
- Экспериментальный JIT-компилятор на основе Java
- совместное использование данных класса
- Расширение языкового тега Unicode
- корневой сертификат
- Модель управления версиями на основе времени
Что нового в Java 11
1. Работа со строками
Класс String является наиболее часто используемым классом в Java, а JDK 11 добавляет ряд полезных методов обработки строк.
- isBlank() оценивается как нуль.
- strip() удалить начальные и конечные пробелы
- stripLeading() удаляет начальные пробелы из строк
- stripTrailing() удаляет конечные пробелы из строки
- lines() разбивает полученный строковый поток.
- Repeat() дублирует строку
// 判断字符串是否为空白
" ".isBlank(); // true
// 去除首尾空格
" jay ".strip(); // "jay"
// 去除首部空格
" jay ".stripLeading(); // "jay "
去除字符串尾部空格
" jay ".stripLeading(); // " jay"
// 行数统计
"a\nb\nc".lines().count(); // 3
// 复制字符串
"jay".repeat(3); // "jayjayjay"
2. Синтаксис локальной переменной для лямбда-параметров
Вывод типа локальной переменной — это новая функция, представленная в Java 10, но ее нельзя использовать в лямбда-выражениях. Java 11 снова инновационный, он позволяет разработчикам использовать var в лямбда-выражениях для объявления параметров.
var map = new HashMap<String, Object>();
map.put("公众号", "捡田螺的小男孩");
map.forEach((var k, var v) -> {
System.out.println(k + ": " + v);
});
3. Стандартизированный HTTP-клиент
Java 9 представила Http Client API, Java 10 обновила его, а Java 11 стандартизировала. После этих нескольких версий Http Client был почти полностью переписан для поддержки HTTP/1.1 и HTTP/2, а также веб-сокетов.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://github.com/whx123/JavaHome"))
.GET()
.build();
// 同步
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// 异步
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
4. Скомпилируйте и запустите исходный код одной командой
Java 11 расширяет возможности средства запуска Java для запуска одного файла исходного кода Java.
- До Java 11 для запуска исходного кода Java его необходимо сначала скомпилировать, а затем запустить.
// 编译
javac Jay.java
// 运行
java Jay
- После Java 11 вы можете сделать это с помощью всего одной команды Java.
java Jay.java
5. ZGC: масштабируемый сборщик мусора с низкой задержкой
ZGC, Z Garbage Collector (сборщик мусора или сборщик мусора). Это масштабируемый сборщик мусора с малой задержкой. ZGC в основном предназначен для достижения следующих целей:
- Время паузы GC не превышает 10 мс
- Может обрабатывать как небольшие кучи в несколько сотен МБ, так и большие кучи в несколько терабайт.
- Пропускная способность приложений не упадет более чем на 15% (по сравнению с алгоритмом рециркуляции G1).
- На этой основе удобно вводить новые возможности GC и использовать colord
- Оптимизация иглы и барьеров нагрузки закладывает основу
- В настоящее время поддерживает только Linux/x64-битные платформы.
6. Некоторые другие функции
- Добавьте сборщик мусора Epsilon.
- Поддержка протокола TLS 1.3.
- Инструмент анализа бортового самописца
- Константы файла динамического класса
- Профилирование кучи с низкими издержками
Что нового в Java 12
1. Расширение выражения переключения (функция предварительного просмотра)
В традиционном операторе switch легко пропустить разрыв записи и сделать ошибки, а метод записи не является кратким и элегантным.
До Java 12
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
break;
case TUESDAY:
System.out.println(7);
break;
case THURSDAY:
case SATURDAY:
System.out.println(8);
break;
case WEDNESDAY:
System.out.println(9);
break;
}
После JDk 12 выражения Switch были улучшены, чтобы принимать как операторы, так и выражения.
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
2. Компактный формат данных
JDK 12 добавляет NumberFormat для форматирования комплексных чисел.
NumberFormat numberFormat = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT);
System.out.println(numberFormat.format(100000));
//output
10万
3. Строка поддерживает операции преобразования и отступа.
- transform Преобразование строки, которое можно использовать с функциональным интерфейсом Function.
List<String> list1 = List.of("jay", " 捡田螺的小男孩");
List<String> list2 = new ArrayList<>();
list1.forEach(element ->
list2.add(element.transform(String::strip)
.transform((e) -> "Hello," + e))
);
list2.forEach(System.out::println);
//输出
Hello,jay
Hello,捡田螺的小男孩
- выравнивание отступов, добавление пробелов и удаление пробелов в начале каждой строки
String result = "Java\n Python\nC".indent(3);
System.out.println(result);
//输出
Java
Python
C
4. Files.mismatch(Path, Path)
В Java 12 добавлен метод несоответствия, который возвращает первое несоответствие или -1L, если несоответствия нет.
public static long mismatch(Path path, Path path2) throws IOException;
Пример кода:
Path file1 = Paths.get("c:\\jay.txt");
Path file2 = Paths.get("c:\\捡田螺的小男孩.txt");
try {
long fileMismatch = Files.mismatch(file1, file2);
System.out.println(fileMismatch);
} catch (IOException e) {
e.printStackTrace();
}
5. Teeing Collector
Teeing Collector — это новая утилита для сбора данных, представленная в Streams API. Ее функция заключается в объединении результатов двух сборщиков. Формат API следующий:
public static <T, R1, R2, R>
Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
Collector<? super T, ?, R2> downstream2,
BiFunction<? super R1, ? super R2, R> merger)
Просто посмотрите на пример кода, ниже приведен пример нахождения среднего балла и общего балла студентов.
List<Student> studentList= Arrays.asList(
new Student("jay", 90),
new Student("捡田螺的小男孩", 100),
new Student("捡表情的小男孩", 80)
);
String teeingResult=studentList.stream().collect(
Collectors.teeing(
Collectors.averagingInt(Student::getScore),
Collectors.summingInt(Student::getScore),
(s1,s2)-> s1+ ":"+ s2
)
);
System.out.println(teeingResult); //90:270
6. Другие функции
- Поддержка юникода 11 (684 новых символа, 11 новых блоков, 7 новых скриптов)
- API констант JVM (главным образом в новом пакете java.lang.invoke.constant определяется ряд символьных ссылочных типов на основе значений, способных описывать каждый тип загружаемой константы).
- Shenandoah GC (сборщик мусора с малым временем паузы)
- Продвижение сборщика G1 (отказ от сбора смешанной коллекции, своевременный возврат неиспользуемой выделенной памяти)
- CDS-файл по умолчанию
- Бенчмарк JMH
Что нового в Java 13
Расширение выражения переключения (представление ключевого слова yield)
Традиционный переключатель:
private static String getText(int number) {
String result = "";
switch (number) {
case 1, 2:
result = "one or two";
break;
case 3:
result = "three";
break;
case 4, 5, 6:
result = "four or five or six";
break;
default:
result = "unknown";
break;
После Java 13 оператор value break больше не компилируется, а использует yield для возврата значения.
private static String getText(int number) {
return switch (number) {
case 1, 2:
yield "one or two";
case 3:
yield "three";
case 4, 5, 6:
yield "four or five or six";
default:
yield "unknown";
};
}
2. Обновление текстового блока
До Java 13 строки нельзя было использовать в нескольких строках, и их нужно было экранировать с помощью символов новой строки или коннекторов новой строки и т. д. В любом случае, это было очень хлопотно и трудно поддерживать.
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, 捡田螺的小男孩</p>\n" +
" </body>\n" +
"</html>\n";
После Java 13 это намного освежает~
String html = """
<html>
<body>
<p>Hello, 捡田螺的小男孩</p>
</body>
</html>
""";
3. Рефакторинг SocketAPI
- Традиционные API-интерфейсы Java Socket (java.net.ServerSocket и java.net.Socket) полагаются на внутреннюю реализацию SocketImpl.
- До Java 13, используя PlainSocketImpl в качестве конкретной реализации SocketImpl .
- Новая низкоуровневая реализация в Java 13, которая представляет реализацию NioSocketImpl для замены реализации PlainSocketImpl для SocketImpl, которая использует ту же внутреннюю инфраструктуру, что и реализация NIO (новый ввод-вывод), и интегрируется с существующим механизмом буферного кэширования в Together.
Простой пример сокета:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketAPITest {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8080)){
boolean runFlag = true;
while(runFlag){
Socket clientSocket = serverSocket.accept();
//搞事情
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Запустите приведенный выше пример и посмотрите, выводятся ли следующие ключевые слова ~
[class,load] sun.nio.ch.NioSocketImpl
4.FileSystems.newFileSystem новый метод
Следующие три новых метода были добавлены в класс FileSystems, чтобы упростить использование поставщиков файловых систем, которые обрабатывают содержимое файлов как файловые системы:
- 1. новая файловая система (путь)
- 2. newFileSystem(Путь, Карта
) - 3. newFileSystem(Path, Map
, ClassLoader)
5. Усовершенствованный ZGC для освобождения неиспользуемой памяти
- ZGC — самая известная функция сборки мусора, представленная в Java 11, масштабируемый сборщик мусора с малой задержкой. Но при фактическом использовании он не может активно освобождать неиспользуемую память для операционной системы.
- Улучшения ZGC в Java 13, в том числе освобождение неиспользуемой памяти для операционной системы, поддержка максимального размера кучи 16 ТБ и параметр JVM -XX:SoftMaxHeapSize для мягкого ограничения размера кучи.
6. Другие функции
- Динамическое архивирование CDS, которое расширяет функцию совместного использования данных класса, представленную в Java 10, упрощает использование архивирования CDS.
- Новые методы класса String для текстовых блоков, такие как formatted(Object...args), stripIndent() и т. д.
Что нового в Java 14
1. пример сопоставления с образцом
Традиционный способ использования instanceof:
if (person instanceof Singer) {
Singer singer = (Singer) person;
singer.sing();
} else if (person instanceof Writer) {
Writer writer = (Writer) person;
writer.write();
}
После улучшений сопоставления шаблонов Java 14 с instanceof
if (person instanceof Singer singer) {
singer.sing();
} else if (person instanceof Writer writer) {
writer.write();
}
2. Тип записи (функция предварительного просмотра)
В Java 14 в качестве функции предварительного просмотра был представлен тип Record, который чем-то похож на аннотацию Lombok @Data.Давайте рассмотрим пример:
public record Person(String name, int age) {
public static String address;
public String getName() {
return name;
}
}
Результат декомпиляции:
public final class Person extends java.lang.Record {
private final java.lang.String name;
private final java.lang.String age;
public Person(java.lang.String name, java.lang.String age) { /* compiled code */ }
public java.lang.String getName() { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public java.lang.String name() { /* compiled code */ }
public java.lang.String age() { /* compiled code */ }
}
Можно обнаружить, что когда класс объявляется с записью, класс автоматически будет иметь следующие характеристики:
- Метод строительства
- метод hashCode()
- метод равных()
- метод toString()
- Объекты класса модифицируются ключевым словом final и не могут быть унаследованы.
3. Выражение переключения — нормализация
Выражение switch ранее находилось на этапе предварительного просмотра в Java 12 и Java 13, и, наконец, оно стандартизировано в Java 14 как стабильная версия.
- Java 12 представляет синтаксис Lambda для выражений переключения
- Java 13 использует yield вместо ключевого слова break для возврата возвращаемого значения выражения.
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if (day.isEmpty()) {
yield "Please insert a valid day.";
} else {
yield "Looks like a Sunday.";
}
}
};
System.out.println(result);
4. Улучшить информацию о подсказках NullPointerExceptions
До Java 14:
String name = song.getSinger().getSingerName()
//堆栈信息
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.main(NullPointerTest.java:6)
Java 14, вводя параметр JVM -XX:+ShowCodeDetailsInExceptionMessages, вы можете получить более подробную информацию о вызове в исключении нулевого указателя.
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Singer.getSingerName()"
because the return value of "rainRow.getSinger()" is null
at NullPointerExample.main(NullPointerTest.java:6)
5. Другие функции
- Распределение памяти с учетом NUMA для G1
- Удалить сборщик мусора CMS
- GC поддерживает системы MacOS и Windows.
Что нового в Java 15
1. Алгоритм цифровой подписи EdDSA
- Криптографические подписи реализуются с использованием алгоритма цифровой подписи Эдвардса-Кривой (EdDSA).
- По сравнению с другими схемами подписи EdDSA имеет более высокую безопасность и производительность.
- Поддерживается многими другими криптографическими библиотеками (например, OpenSSL, BoringSSL).
2.Sealed Classes (закрытый класс, превью)
Закрытый класс, который может быть закрытым классом, закрытым интерфейсом, не позволяет другим классам или интерфейсам расширять или реализовывать их.
public abstract sealed class Singer
permits Jay, Eason{
...
}
Класс Singer модифицируется запечатанным и является закрытым классом, который может быть унаследован только двумя указанными подклассами (Jay, Eason).
3. Скрытые классы
- Скрытые классы изначально предназначены для фреймворков.
- Доступ к скрытым классам возможен только через отражение, а не напрямую через байт-код других классов.
4. Remove the Nashorn JavaScript Engine
- Nashorn настолько сложно поддерживать, что удаление движка Nashorn JavaScript становится необходимостью.
- Фактически, он был помечен как устаревший еще в JDK 11.
5. Повторно реализовать устаревший API DatagramSocket.
- Повторно реализовать старый API DatagramSocket
- Изменены java.net.DatagramSocket и java.net.MulticastSocket на более простые современные низкоуровневые реализации.
6. Другое
- Отключить и отказаться от предвзятой блокировки
- instanceof автоматически сопоставляет шаблоны (предварительная версия)
- ZGC, масштабируемый сборщик мусора с малой задержкой. (исправленный)
- Текстовые блоки, текстовые функции теперь положительные (предварительный просмотр JDK 13 и 14, 14, наконец, положительный)
- Удалите порты Solaris и SPARC
- API доступа к внешней памяти (позволяет приложениям Java безопасно и эффективно обращаться к внешней памяти за пределами кучи Java).
- Вторичный предварительный просмотр типа записи (предварительный просмотр в Java 14)
Ссылка и спасибо
- Новые функции JDK6
- Что нового в Java 7
- Обзор новых функций в Java 9
- Что нового в Java 9
- Знакомство с новыми функциями Java 10.
- Знакомство с новыми функциями Java 11.
- Обзор новых функций в Java 13
- Обзор новых функций в Java 14
- Выпущен JDK/Java 15
- [Java 15 официально выпущена, 14 новых функций, освежите свое познание! !
](Блог Woohoo.cn на.com/Java stack/Afraid…)