├── .gitignore ├── LICENSE ├── README.md ├── lib ├── hamcrest-core-1.3.jar ├── junit-4.13.2.jar └── lombok-1.18.30.jar ├── resources ├── 20220128-技术分享.md ├── JamesGosling_Java17.png ├── Java新特性.png ├── Java新特性.xmind ├── Java新特性_2024_bak.xmind ├── idea高版本jdk配置 │ ├── 01_pom文件指定jdk位置.png │ ├── 02_设置java编译器的class版本.png │ ├── 03_工程的JDK版本设置.png │ └── 04_JUnit测试的模板中加入启用预览参数.png └── 参考资料 │ ├── 01-尚硅谷_宋红康_Java8的新特性.pdf │ ├── 02-尚硅谷_宋红康_Java9&Java10&Java11新特性.pdf │ ├── 03-尚硅谷_宋红康_深入解读Java12&13新特性.pdf │ ├── 04-尚硅谷_宋红康_超实用的Java14新特性.pdf │ ├── 尚硅谷_宋红康_波澜不惊的Java15新特性.mmap │ └── 波澜不惊的Java15新特性 尚硅谷-宋红康.xmind └── src └── com └── hepengju ├── java05 ├── new01_autoboxing │ ├── AutoboxingJavap.java │ └── _Autoboxing.java ├── new02_varargs │ └── _Varargs.java ├── new03_enhanceFor │ └── _EnhanceFor.java ├── new04_staticimport │ └── _StaticImport.java ├── new05_enum │ ├── ColorEnum.java │ ├── SpecialEnum.java │ ├── WorkdayEnum.java │ └── _Enum.java ├── new06_generic │ ├── Fruit01Generator.java │ ├── Fruit02Generator.java │ ├── Generator.java │ ├── Generic.java │ ├── GenericMethodBase.java │ ├── GenericMethodInClass.java │ ├── Person.java │ ├── PersonComparator.java │ ├── PersonGeneric.java │ ├── StringGenerator.java │ ├── Student.java │ ├── StudentComparator.java │ ├── _Generic.java │ └── _GenericReflect.java ├── new07_annotation │ ├── A_Anno.java │ ├── B_Anno.java │ ├── C_Anno.java │ ├── P1_Anno.java │ ├── P2_Anno.java │ ├── Parent.java │ ├── _Annotation.java │ ├── package-info.java │ └── spring │ │ └── _SpringAnno.java ├── new08_juc │ ├── _JUC.java │ └── _TimeUnit.java ├── new09_introspector │ └── _Introspector.java ├── new10_processBuilder │ ├── ExecUtil.java │ └── _ProcessBuilder.java ├── new11_other │ └── _Other.java └── package-info.java ├── java06 ├── new01_sciprtEngine │ └── _ScriptEngine.java ├── new02_dynamicCompile │ └── _DynamicCompile.java ├── new12_overrideBug │ └── _OverrideBug.java └── package-info.java ├── java07 ├── new01_binaryLiteral │ └── _BinaryLiteral.java ├── new02_numberUnderline │ └── _NumberUnderline.java ├── new03_switchString │ └── _SwitchString.java ├── new04_genericInference │ └── _GenericInference.java ├── new07_twr │ └── _TWR.java ├── new08_nio │ └── _NIO.java ├── new09_forkjoin │ ├── ForkJoinCalculate.java │ └── _ForkJoin.java ├── new10 │ └── _Other.java └── package-info.java ├── java08 ├── new01_lambda │ └── _Lambda.java ├── new02_functionalInterface │ └── _FunctionalInterface.java ├── new03_methodReference │ └── _MethodReference.java ├── new04_streamAPI │ ├── Person.java │ └── _StreamAPI.java ├── new05_optional │ ├── Car.java │ ├── Insurance.java │ ├── Person.java │ └── _Optional.java ├── new06_interfaceMethod │ └── _InterfaceMethod.java ├── new07_collector │ ├── Person.java │ └── _Collector.java ├── new08_comparator │ ├── Person.java │ └── _Comparator.java ├── new09_iostream │ ├── _IOStream.java │ └── tmp.txt ├── new10_newDateTime │ └── _NewDateTime.java ├── new11_base64 │ ├── Base64Util.java │ └── _Base64.java ├── new12_completableFuture │ ├── Car.java │ └── _CompletableFuture.java ├── new13_repeatalAnnotation │ ├── MyAnno.java │ ├── MyAnnos.java │ └── _RepeatAnnotation.java ├── new14_parameterName │ └── _ParameterName.java ├── new20_other │ └── _Other.java └── package-info.java ├── java09 ├── new01_jigsaw │ ├── module_01 │ │ └── _Person.java │ └── module_02 │ │ └── _Module.java ├── new02_jshell │ └── _Jshell.java ├── new03_interface │ └── _Interface.java ├── new04_diamondoperator │ └── _DiamondOperator.java ├── new05_twr │ └── _TWR.java ├── new06_collection │ └── _Collection.java ├── new07_stream │ └── _Stream.java ├── new08_httpclient │ └── _HttpClient.java ├── new09_jsonAPI │ └── _JsonAPI.java ├── new10_moneyAPI │ └── _MoneyAPI.java ├── new11_other │ ├── _CompactStrings.java │ ├── _JIT.java │ ├── _JavaDoc.java │ ├── _Locking.java │ ├── _Logging.java │ ├── _MultiResolutionImages.java │ ├── _Multijar.java │ ├── _Nashorn.java │ ├── _Optional.java │ ├── _SJavac.java │ ├── _SegCodeCache.java │ └── _UnderScore.java └── package-info.java ├── java10 ├── new01_varinference │ └── _VarInference.java ├── new02_gcimprove │ └── _GCimprove.java ├── new03_localhandshake │ └── _LocalHandShake.java ├── new04_heapallocation │ └── _HeapAllication.java ├── new05_extunicode │ └── _ExtUnicode.java ├── new06_jitcompiler │ └── _JITCompiler.java ├── new07_rootcertificates │ └── _RootCertificates.java ├── new08_ca │ └── _new08_ca.java ├── new09_consolidatejdkf │ └── _RemoveJavah.java ├── new10_removejavah │ └── _RemoveJavah.java ├── new11_other │ └── _API.java └── package-info.java ├── java11 ├── new01_string │ └── _String.java ├── new02_varforlambda │ └── _VarForLambda.java ├── new03_httpClient │ └── _HttpClient.java ├── new04_unicode10 │ └── _Unicode10.java ├── new05_simplify │ └── _Simplify.java ├── new06_abandon │ └── _Abandon.java ├── new07_epsilon │ ├── Garbage.java │ └── _Epsilon.java ├── new08_jfr │ └── _JFR.java ├── new09_zgc │ └── _ZGC.java ├── new10_lowoverhead │ └── _LowOverhead.java ├── new11_keyagreement │ └── _KeyAgreement.java ├── new12_other │ └── _Other.java └── package-info.java ├── java12 ├── new01_switch │ └── _Switch.java ├── new02_JVMConstantsAPI │ └── _JVMConstantsAPI.java ├── new03_compactNumber │ └── _CompactNumber.java ├── new04_other │ └── _Other.java └── package-info.java ├── java13 ├── new01_switch │ └── _Switch.java ├── new02_textblock │ └── _TextBlock.java ├── new03_reImplSocket │ └── _ReImplSocket.java └── package-info.java ├── java14 ├── new01_instanceof │ └── _Instanceof.java ├── new02_jpackage │ └── _JPackage.java ├── new03_JFREventStreaming │ └── _JFREventStreaming.java ├── new04_helpfulNPE │ └── _HelpfulNPE.java ├── new05_record │ └── _Record.java └── package-info.java ├── java15 ├── new01_sealedclass │ └── _SealedClass.java ├── new02_hiddenclass │ └── _HiddenClass.java ├── new03_textblock │ └── _TextBlock.java └── package-info.java ├── java16 ├── new01_toList │ └── _StreamToList.java └── package-info.java ├── java17 ├── new01_randomgenerator │ └── _RandomGenerator.java ├── new03_sealedclass │ └── _SealedClass.java ├── new04_hexformat │ └── _HexFormat.java └── package-info.java ├── java18 ├── new01_utf8 │ └── _UTF8.java ├── new02_webserver │ └── _SimpleWebServer.java ├── new03_snippet │ ├── ShowOptional.java │ └── _Snippet.java └── package-info.java ├── java19 ├── new01_newmapset │ └── _NewMapSet.java ├── new02_minguodate │ └── _MinguoDate.java └── package-info.java ├── java20 └── package-info.java ├── java21 ├── new01_sequenced_collections │ └── _SequencedCollections.java ├── new02_record_patterns │ └── _RecordPatterns.java ├── new03_switch_patterns │ └── _SwitchPatterns.java ├── new04_visual_threads │ └── _VirtualThread.java └── package-info.java ├── java22 ├── new01_unnamed_variables │ └── _UnnamedVariables.java └── package-info.java ├── jvm ├── JVM00Util.java ├── JVM01Base.java ├── JVM02Heap.java ├── JVM03Stack.java ├── JVM04Perm.java ├── JVM05DirectMemory.java └── JVM06TLAB.java └── whynew ├── _01_JDBC.java ├── package-info.java └── person.sql /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | out 9 | gen### macOS template 10 | # General 11 | .DS_Store 12 | .AppleDouble 13 | .LSOverride 14 | 15 | # Icon must end with two \r 16 | Icon 17 | 18 | # Thumbnails 19 | ._* 20 | 21 | # Files that might appear in the root of a volume 22 | .DocumentRevisions-V100 23 | .fseventsd 24 | .Spotlight-V100 25 | .TemporaryItems 26 | .Trashes 27 | .VolumeIcon.icns 28 | .com.apple.timemachine.donotpresent 29 | 30 | # Directories potentially created on remote AFP share 31 | .AppleDB 32 | .AppleDesktop 33 | Network Trash Folder 34 | Temporary Items 35 | .apdisk 36 | ### Java template 37 | # Compiled class file 38 | *.class 39 | 40 | # Log file 41 | *.log 42 | 43 | # BlueJ files 44 | *.ctxt 45 | 46 | # Mobile Tools for Java (J2ME) 47 | .mtj.tmp/ 48 | 49 | # Package Files # 50 | *.jar 51 | *.war 52 | *.nar 53 | *.ear 54 | *.zip 55 | *.tar.gz 56 | *.rar 57 | 58 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 59 | hs_err_pid* 60 | ### Eclipse template 61 | 62 | .metadata 63 | bin/ 64 | tmp/ 65 | *.tmp 66 | *.bak 67 | *.swp 68 | *~.nib 69 | local.properties 70 | .settings/ 71 | .loadpath 72 | .recommenders 73 | 74 | # External tool builders 75 | .externalToolBuilders/ 76 | 77 | # Locally stored "Eclipse launch configurations" 78 | *.launch 79 | 80 | # PyDev specific (Python IDE for Eclipse) 81 | *.pydevproject 82 | 83 | # CDT-specific (C/C++ Development Tooling) 84 | .cproject 85 | 86 | # CDT- autotools 87 | .autotools 88 | 89 | # Java annotation processor (APT) 90 | .factorypath 91 | 92 | # PDT-specific (PHP Development Tools) 93 | .buildpath 94 | 95 | # sbteclipse plugin 96 | .target 97 | 98 | # Tern plugin 99 | .tern-project 100 | 101 | # TeXlipse plugin 102 | .texlipse 103 | 104 | # STS (Spring Tool Suite) 105 | .springBeans 106 | 107 | # Code Recommenders 108 | .recommenders/ 109 | 110 | # Scala IDE specific (Scala & Java development for Eclipse) 111 | .cache-main 112 | .scala_dependencies 113 | .worksheet 114 | 115 | # 手动添加 116 | .classpath 117 | .project 118 | .settings 119 | target/ 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![图片展示](./resources/Java%E6%96%B0%E7%89%B9%E6%80%A7.png) 2 | 3 | # java-new-features 4 | Java新特性 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 5 | 6 | ## 项目目标 7 | 1. 列举Java5-21版本的关键新特性 8 | 2. 对每个新特性进行全面的阐述与代码示例 9 | 10 | ## 新特性目标(为什么需要不断升级) 11 | - 目标:速度更快,代码更少,更加安全 12 | - 原因:语言必须发展,否则它们就有变得无关紧要的风险。 -- Brian Goetz 13 | 14 | ## 官网新特性 15 | - [OracleJDK](https://www.oracle.com/java/technologies/javase/jdk-relnotes-index.html) 16 | - [OpenJDK ](http://openjdk.java.net/projects/jdk/) 17 | 18 | # JCP/JEP/JSR 19 | - JCP: [Java Community Process](https://www.jcp.org/en/home/index) 20 | * Java社区进程 21 | * JCP成立于1998年, 由社会各界Java组成的社区, 规划和领导Java的发展 22 | - JEP: [JDK Enhancement Proposals](http://openjdk.java.net/jeps/0) 23 | * jdk改进提案, 非正式的规范 24 | * OpenJDK社区搜集增强jdk提案的过程 25 | - JSR: [Java Specification Requests](https://www.jcp.org/en/jsr/platform) 26 | * java规范请求, 标准化技术规范的正式请求 27 | * 由JCP成员向委员会提交的Java发展提案, 经过一系列流程后, 如果通过最终会体现在未来的Java中 28 | 29 | -------------------------------------------------------------------------------- /lib/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/lib/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /lib/junit-4.13.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/lib/junit-4.13.2.jar -------------------------------------------------------------------------------- /lib/lombok-1.18.30.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/lib/lombok-1.18.30.jar -------------------------------------------------------------------------------- /resources/20220128-技术分享.md: -------------------------------------------------------------------------------- 1 | ## 语言发展 2 | - 语言必须发展,否则它们就有变得无关紧要的风险 -- Brian Goetz 3 | 4 | ## Java5-8容易被忽略的特性梳理 5 | - Java6脚本引擎 6 | - Java7数据变量对下划线的支持 7 | - Java7的TWR(异常处理改进) 8 | - Java8的函数式接口、方法引用 9 | 10 | ## Java9-17新版本关键新特性梳理 11 | - java9的模块化、jshell(REPL)、String、集合的of方法 12 | - java11的var、HttpClient、GraalVM、java执行单java文件、EpsilonGC、ZGC 13 | - java17的记录类、密封类、文本框、instanceof模式匹配、jpackage、switch表达式、优化的NPE提示 -------------------------------------------------------------------------------- /resources/JamesGosling_Java17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/JamesGosling_Java17.png -------------------------------------------------------------------------------- /resources/Java新特性.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/Java新特性.png -------------------------------------------------------------------------------- /resources/Java新特性.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/Java新特性.xmind -------------------------------------------------------------------------------- /resources/Java新特性_2024_bak.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/Java新特性_2024_bak.xmind -------------------------------------------------------------------------------- /resources/idea高版本jdk配置/01_pom文件指定jdk位置.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/idea高版本jdk配置/01_pom文件指定jdk位置.png -------------------------------------------------------------------------------- /resources/idea高版本jdk配置/02_设置java编译器的class版本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/idea高版本jdk配置/02_设置java编译器的class版本.png -------------------------------------------------------------------------------- /resources/idea高版本jdk配置/03_工程的JDK版本设置.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/idea高版本jdk配置/03_工程的JDK版本设置.png -------------------------------------------------------------------------------- /resources/idea高版本jdk配置/04_JUnit测试的模板中加入启用预览参数.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/idea高版本jdk配置/04_JUnit测试的模板中加入启用预览参数.png -------------------------------------------------------------------------------- /resources/参考资料/01-尚硅谷_宋红康_Java8的新特性.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/参考资料/01-尚硅谷_宋红康_Java8的新特性.pdf -------------------------------------------------------------------------------- /resources/参考资料/02-尚硅谷_宋红康_Java9&Java10&Java11新特性.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/参考资料/02-尚硅谷_宋红康_Java9&Java10&Java11新特性.pdf -------------------------------------------------------------------------------- /resources/参考资料/03-尚硅谷_宋红康_深入解读Java12&13新特性.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/参考资料/03-尚硅谷_宋红康_深入解读Java12&13新特性.pdf -------------------------------------------------------------------------------- /resources/参考资料/04-尚硅谷_宋红康_超实用的Java14新特性.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/参考资料/04-尚硅谷_宋红康_超实用的Java14新特性.pdf -------------------------------------------------------------------------------- /resources/参考资料/尚硅谷_宋红康_波澜不惊的Java15新特性.mmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/参考资料/尚硅谷_宋红康_波澜不惊的Java15新特性.mmap -------------------------------------------------------------------------------- /resources/参考资料/波澜不惊的Java15新特性 尚硅谷-宋红康.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/resources/参考资料/波澜不惊的Java15新特性 尚硅谷-宋红康.xmind -------------------------------------------------------------------------------- /src/com/hepengju/java05/new01_autoboxing/AutoboxingJavap.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new01_autoboxing; 2 | 3 | /** 4 | * 反编译查看自动拆装箱的本质 5 | * 6 | * 7 | *
javac AutoboxingJavap.java 编译 8 | *
javap -c AutoboxingJavap 反编译 9 | * 10 | * @author hepengju 11 | * 12 | */ 13 | public class AutoboxingJavap { 14 | 15 | public static void main(String[] args) { 16 | @SuppressWarnings("unused") 17 | Integer i = 10; // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 18 | 19 | Integer m = Integer.valueOf(10); 20 | @SuppressWarnings("unused") 21 | int j = m; // Method java/lang/Integer.intValue:()I 22 | } 23 | } 24 | 25 | 26 | /* 27 | * 反编译结果: 28 | * 29 | Compiled from "AutoboxingJavap.java" 30 | public class com.hepengju.java05.new01_autoboxing.AutoboxingJavap { 31 | public com.hepengju.java05.new01_autoboxing.AutoboxingJavap(); 32 | Code: 33 | 0: aload_0 34 | 1: invokespecial #1 // Method java/lang/Object."":()V 35 | 4: return 36 | 37 | public static void main(java.lang.String[]); 38 | Code: 39 | 0: bipush 10 40 | 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 41 | 5: astore_1 42 | 6: bipush 10 43 | 8: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 44 | 11: astore_2 45 | 12: aload_2 46 | 13: invokevirtual #3 // Method java/lang/Integer.intValue:()I 47 | 16: istore_3 48 | 17: return 49 | } 50 | 51 | */ -------------------------------------------------------------------------------- /src/com/hepengju/java05/new01_autoboxing/_Autoboxing.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new01_autoboxing; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 自动拆装箱(Autoboxing/Unboxing): 基本数据类型和包装类之间的自动转换 7 | * 8 | *
 9 |  *  自动装箱:基本类型 --> 包装类型, 通过调用valueOf方法实现(可能从缓存中获取)
10 |  *  自动拆箱:包装类型 --> 基本类型, 通过调用包装器的 xxxValue方法实现(如Integer.intValue(a))
11 |  * 
12 |  *  对应: 基本数据类型对应的包装器类型
13 |  *      byte(1字节)       Byte
14 |  *      short(2字节)      Short	
15 |  *      int(4字节)        Integer
16 |  *      long(8字节)       Long
17 |  *      float(4字节)      Float
18 |  *      double(8字节)     Double
19 |  *      char(2字节)       Character
20 |  *      boolean(未定)     Boolean
21 |  *  
22 |  *  缓存: Integer、Short、Byte、Character、Long 包装类型有缓存机制(cache数组)
23 |  *       Boolean类型有TRUE 和 FALSE两个静态成员
24 |  *       Double和Float没有缓存机制, 因为它们是不连续的
25 |  * 
26 |  *  注意: 1. 我们知道,"=="运算符既可以用来比较基本类型变量和引用类型变量。当两个操作数都是包装器类型的变量时,判定标准为他们是否指向同一个对象;
27 |  *       而如果其中有一个操作数是表达式(即包含算术运算)则会先进行自动拆箱,再进行对应基本类型变量比较。
28 |  *       2. 包装类型重写了equals方法,包装类型的equals不会进行类型的转换,类型不同的包装类型的变量直接被判定为false,尽管他们的数值有可能是相等的。
29 |  * 
30 | * 31 | * @see AutoboxingJavap 反编译查看自动拆装箱的本质 32 | * @see 关于java的自动拆装箱若干细节问题 33 | * @see 深入剖析Java中的装箱和拆箱 34 | * @see 真的知道Java中boolean类型占用多少个字节吗? 35 | * 36 | * @author hepengju 37 | * 38 | */ 39 | public class _Autoboxing { 40 | 41 | /** 42 | * 自动装箱 43 | */ 44 | @Test public void testAutoboxing() { 45 | @SuppressWarnings("unused") 46 | Integer i = 10; 47 | } 48 | 49 | /** 50 | * 自动拆箱 51 | */ 52 | @Test public void testUnboxing() { 53 | @SuppressWarnings("unused") 54 | int i = Integer.valueOf(10); 55 | } 56 | 57 | /** 58 | * 缓存机制(-128到127) 59 | * 60 | * @see Integer#valueOf(int) 61 | * @see Short#valueOf(short) 62 | * @see Byte#valueOf(byte) 63 | * @see Character#valueOf(char) 64 | * @see Long#valueOf(long) 65 | */ 66 | @Test public void testIntegerCache() { 67 | Integer m = 100; 68 | Integer n = 100; 69 | Integer x = 300; 70 | Integer y = 300; 71 | 72 | System.out.println(m == n); // true 73 | System.out.println(x == y); // false 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new02_varargs/_Varargs.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new02_varargs; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 7 | * 可变参数(Varargs) 8 | * 9 | *
10 |  *  说明: 只要在一个形参的“类型”与“参数名”之间加上三个连续的“.”就可以让它和不确定个实参相匹配
11 |  * 
12 |  *  注意: 1.不定项参数必须放在参数列表最后一个
13 |  *       2.不定项参数只能有一个(多个,必然有一个不是最后一个)
14 |  *       3.重载时优先调用参数个数固定的方法
15 |  * 
16 | * 17 | * @see 深入了解JAVA可变长度的参数(Varargs) 18 | * 19 | * @author hepengju 20 | * 21 | */ 22 | public class _Varargs { 23 | 24 | /** 25 | * 可变参数 26 | */ 27 | @Test public void testVarargs() { 28 | // 传入0或多个参数 29 | printAll(); 30 | printAll("孙悟空", "猪八戒"); // 优先调用参数个数固定的方法: printAll(String str1,String str2) 31 | printAll("孙悟空", "猪八戒", "唐僧"); 32 | printAll("孙悟空", "猪八戒", "唐僧", "沙和尚"); 33 | 34 | // 直接传入数组 35 | String[] arr = new String[] { "孙悟空", "猪八戒" }; 36 | printAll(arr); 37 | } 38 | 39 | public void printAll(String... strs) { 40 | for (int i = 0; i < strs.length; i++) { 41 | String str = strs[i]; 42 | System.out.println(str); 43 | } 44 | System.out.println("------"); 45 | } 46 | 47 | public void printAll(String str1, String str2) { 48 | System.out.println(str1); 49 | System.out.println(str2); 50 | System.out.println("******"); 51 | } 52 | 53 | /** 54 | * 求和示例 55 | */ 56 | @Test public void testBaseType() { 57 | System.out.println(sum()); 58 | System.out.println(sum(1)); 59 | System.out.println(sum(1, 2)); 60 | 61 | int[] arr = { 1, 2, 3 }; 62 | System.out.println(sum(arr)); 63 | 64 | // The method sum(int...) in the type _Varargs is not applicable for the arguments (int, int[]) 65 | // System.out.println(sum(1,arr)); 66 | } 67 | 68 | public int sum(int... arr) { 69 | int sum = 0; 70 | for (int i = 0; i < arr.length; i++) { 71 | sum += i; 72 | } 73 | return sum; 74 | } 75 | 76 | //Duplicate method printAll(String[]) in type _Varargs 77 | /* 78 | public void printAll(String[] strs) { 79 | for (int i = 0; i < strs.length; i++) { 80 | String str = strs[i]; 81 | System.out.println(str); 82 | } 83 | System.out.println("-------"); 84 | } 85 | */ 86 | } 87 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new03_enhanceFor/_EnhanceFor.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new03_enhanceFor; 2 | 3 | import java.util.Arrays; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | import org.junit.Test; 8 | 9 | /** 10 | * 11 | * 增强for循环 12 | * 13 | *
14 |  *  场景: 数组,实现 Iterable 接口的集合
15 |  *  目的: 替代迭代器 (底层就是使用迭代器实现的)
16 |  *  
17 |  *  缺点: 1.不能遍历同时获取index
18 |  *       2.不能集合逗号拼接时去掉最后一个
19 |  *       3.不能遍历的同时删除元素
20 |  * 
21 | * 22 | * @author hepengju 23 | * 24 | */ 25 | public class _EnhanceFor { 26 | 27 | /** 28 | * 遍历数组 29 | */ 30 | @Test public void testArray() { 31 | int[] arr = { 1, 2, 3, 4, 5 }; 32 | for (int i : arr) { 33 | System.out.println(i); 34 | } 35 | } 36 | 37 | /** 38 | * 新添加的Iterable接口 39 | * 40 | * @see java.lang.Iterable 41 | */ 42 | @Test public void testIterable() { 43 | List list = Arrays.asList(1,2,3,4); 44 | Iterator iterator = list.iterator(); 45 | while(iterator.hasNext()) { 46 | Integer next = iterator.next(); 47 | System.out.println(next); 48 | } 49 | } 50 | 51 | /** 52 | * 遍历Iterable接口的集合 53 | */ 54 | @Test public void testList() { 55 | List list = Arrays.asList(1,2,3,4); 56 | for (int i : list) { 57 | System.out.println(i); 58 | } 59 | } 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new04_staticimport/_StaticImport.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new04_staticimport; 2 | 3 | import static java.lang.Math.min; 4 | import static java.nio.charset.StandardCharsets.UTF_8; 5 | import static java.util.Comparator.naturalOrder; 6 | import static java.util.Comparator.nullsFirst; 7 | import static java.util.stream.Collectors.joining; 8 | 9 | import java.nio.charset.Charset; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | import org.junit.Test; 14 | 15 | /** 16 | * 静态导入 17 | * 18 | *
19 |  *  说明: 通过使用 import static 就可以不用指定类名而直接使用静态成员,包括静态方法和常量
20 |  * 
21 |  *  区别: import xxxx 和 import static xxxx
22 |  *     * 前者一般导入的是类文件   import java.util.Scanner
23 |  *     * 后者一般是导入静态的方法 import static java.lang.System.out
24 |  * 
25 |  * 
26 |  * @see com.hepengju.java08.new04_streamAPI._StreamAPI#testStreamCompSql
27 |  * 
28 |  * @author hepengju
29 |  *
30 |  */
31 | public class _StaticImport {
32 | 
33 | 	/**
34 | 	 * 静态方法
35 | 	 */
36 | 	@Test public void testMethod() {
37 | 		//int m = Math.min(10, 20);
38 | 		int m = min(10, 20);    // import static java.lang.Math.min;
39 | 		System.out.println(m);  // 10
40 | 	}
41 | 	
42 | 	/**
43 | 	 * 静态常量
44 | 	 */
45 | 	@Test public void testConstant() {
46 | 		//Charset utf8 = StandardCharsets.UTF_8;
47 | 		Charset utf8 = UTF_8;        // import static java.nio.charset.StandardCharsets.UTF_8;
48 | 		System.out.println(utf8);    // UTF-8
49 | 	}
50 | 	
51 | 	/**
52 | 	 * 在Jdk8的Stream流处理中使用静态导入, 极大的减少代码量, 提高代码的可读性
53 | 	 */
54 | 	@Test public void testStreamInJDK8(){
55 |         List list = Arrays.asList("bbbb", null, "zz", "abc");
56 | 	    //String result = list.stream().sorted(Comparator.nullsFirst(Comparator.naturalOrder())).collect(Collectors.joining(","));
57 | 	    /*
58 | 	     * import static java.util.Comparator.naturalOrder;
59 |          * import static java.util.Comparator.nullsFirst;
60 |          * import static java.util.stream.Collectors.joining;
61 | 	     */
62 | 	    String result = list.stream().sorted(nullsFirst(naturalOrder())).collect(joining(","));
63 | 	    System.out.println(result); // null,abc,bbbb,zz
64 | 	}
65 | }
66 | 


--------------------------------------------------------------------------------
/src/com/hepengju/java05/new05_enum/ColorEnum.java:
--------------------------------------------------------------------------------
 1 | package com.hepengju.java05.new05_enum;
 2 | 
 3 | /**
 4 |  * 颜色枚举: 最简单的枚举
 5 |  * 
 6 |  * @author hepengju
 7 |  *
 8 |  */
 9 | public enum ColorEnum {
10 |     RED,BLUE,GREEN
11 | }


--------------------------------------------------------------------------------
/src/com/hepengju/java05/new05_enum/SpecialEnum.java:
--------------------------------------------------------------------------------
 1 | package com.hepengju.java05.new05_enum;
 2 | 
 3 | /**
 4 |  * 
 5 |  * 特殊枚举: 枚举里面有抽象方法
 6 |  * 
 7 |  * @author hepengju
 8 |  *
 9 |  */
10 | public enum SpecialEnum {
11 | 	ONE{
12 | 
13 | 		@Override
14 | 		void say() {
15 | 			System.out.println("one");
16 | 		}
17 | 		
18 | 	},TWO{
19 | 
20 | 		@Override
21 | 		void say() {
22 | 			System.out.println("two");
23 | 		}
24 | 	};
25 | 	
26 | 	//抽象方法
27 | 	abstract void say();
28 | 	
29 | }
30 | 


--------------------------------------------------------------------------------
/src/com/hepengju/java05/new05_enum/WorkdayEnum.java:
--------------------------------------------------------------------------------
 1 | package com.hepengju.java05.new05_enum;
 2 | 
 3 | /**
 4 |  * 工作日枚举: 构造方法里面有参数
 5 |  * 
 6 |  * @author hepengju
 7 |  *
 8 |  */
 9 | public enum WorkdayEnum {
10 | 	MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(7);
11 | 	
12 | 	private int value;
13 | 	
14 | 	//此处只能是private, 否则报错: Illegal modifier for the enum constructor; only private is permitted.
15 | 	// idea提示: Modifier 'private' is redundant for enum constructors (冗余的)
16 | 	WorkdayEnum(int value) {
17 | 		this.value = value;
18 | 	}
19 | 
20 | 	//WorkdayEnum
21 | 	public int getValue() {
22 | 		return this.value;
23 | 	}
24 | 	
25 | }
26 | 


--------------------------------------------------------------------------------
/src/com/hepengju/java05/new06_generic/Fruit01Generator.java:
--------------------------------------------------------------------------------
 1 | package com.hepengju.java05.new06_generic;
 2 | 
 3 | /**
 4 |  * 
 5 |  * 实现泛型接口的类, 未传入泛型实参
 6 |  * 
 7 |  * 
在声明类的时候,需将泛型的声明也一起加到类中 8 | * 9 | * @author hepengju 10 | * 11 | * @param 12 | */ 13 | public class Fruit01Generator implements Generator{ 14 | 15 | @Override 16 | public T next() { 17 | return null; 18 | } 19 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/Fruit02Generator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * 7 | * 实现泛型接口的类, 传入泛型实参 8 | * 9 | *
在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型 10 | *
即:Generator,public T next();中的的T都要替换成传入的String类型。 11 | * 12 | * @author hepengju 13 | * 14 | */ 15 | public class Fruit02Generator implements Generator { 16 | 17 | private String[] fruits = new String[]{"Apple", "Banana", "Pear"}; 18 | 19 | @Override 20 | public String next() { 21 | Random rand = new Random(); 22 | return fruits[rand.nextInt(3)]; 23 | } 24 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/Generator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | /** 4 | * 泛型接口 5 | * 6 | *
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中 7 | * 8 | * @author hepengju 9 | * 10 | * @param 11 | */ 12 | public interface Generator { 13 | public T next(); 14 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/Generic.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | /** 4 | * 泛型类 5 | * 6 | *
此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型 7 | *
在实例化泛型类时,必须指定T的具体类型 8 | * 9 | * @author hepengju 10 | * 11 | * @param 12 | */ 13 | public class Generic{ 14 | 15 | private T key; //key这个成员变量的类型为T, T的类型由外部指定 16 | 17 | public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定 18 | this.key = key; 19 | } 20 | 21 | public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定 22 | return key; 23 | } 24 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/GenericMethodBase.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | /** 4 | * 泛型方法示例 5 | * 6 | * @author hepengju 7 | * 8 | */ 9 | public class GenericMethodBase { 10 | 11 | //这个类是个泛型类,在上面已经介绍过 12 | public class Generic{ 13 | private T key; 14 | 15 | public Generic(T key) { 16 | this.key = key; 17 | } 18 | 19 | //我想说的其实是这个,虽然在方法中使用了泛型,但是这并不是一个泛型方法。 20 | //这只是类中一个普通的成员方法,只不过他的返回值是在声明泛型类已经声明过的泛型。 21 | //所以在这个方法中才可以继续使用 T 这个泛型。 22 | public T getKey(){ 23 | return key; 24 | } 25 | 26 | /** 27 | * 这个方法显然是有问题的,在编译器会给我们提示这样的错误信息"cannot reslove symbol E" 28 | * 因为在类的声明中并未声明泛型E,所以在使用E做形参和返回值类型时,编译器会无法识别。 29 | public E setKey(E key){ 30 | this.key = keu 31 | } 32 | */ 33 | } 34 | 35 | /** 36 | * 这才是一个真正的泛型方法。 37 | * 首先在public与返回值之间的必不可少,这表明这是一个泛型方法,并且声明了一个泛型T 38 | * 这个T可以出现在这个泛型方法的任意位置. 39 | * 泛型的数量也可以为任意多个 40 | * 如:public K showKeyName(Generic container){ 41 | * ... 42 | * } 43 | */ 44 | public T showKeyName(Generic container){ 45 | System.out.println("container key :" + container.getKey()); 46 | //当然这个例子举的不太合适,只是为了说明泛型方法的特性。 47 | T test = container.getKey(); 48 | return test; 49 | } 50 | 51 | //这也不是一个泛型方法,这就是一个普通的方法,只是使用了Generic这个泛型类做形参而已。 52 | public void showKeyValue1(Generic obj){ 53 | System.out.println("泛型测试 key value is " + obj.getKey()); 54 | } 55 | 56 | //这也不是一个泛型方法,这也是一个普通的方法,只不过使用了泛型通配符? 57 | //同时这也印证了泛型通配符如前面所描述的,?是一种类型实参,可以看做为Number等所有类的父类 58 | public void showKeyValue2(Generic obj){ 59 | System.out.println("泛型测试 key value is " + obj.getKey()); 60 | } 61 | 62 | /** 63 | * 这个方法是有问题的,编译器会为我们提示错误信息:"UnKnown class 'E' " 64 | * 虽然我们声明了,也表明了这是一个可以处理泛型的类型的泛型方法。 65 | * 但是只声明了泛型类型T,并未声明泛型类型E,因此编译器并不知道该如何处理E这个类型。 66 | public T showKeyName(Generic container){ 67 | ... 68 | } 69 | */ 70 | 71 | /** 72 | * 这个方法也是有问题的,编译器会为我们提示错误信息:"UnKnown class 'T' " 73 | * 对于编译器来说T这个类型并未项目中声明过,因此编译也不知道该如何编译这个类。 74 | * 所以这也不是一个正确的泛型方法声明。 75 | public void showkey(T genericObj){ 76 | 77 | } 78 | */ 79 | 80 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/GenericMethodInClass.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | /** 4 | * 类中的泛型方法 5 | * 6 | * @author hepengju 7 | * 8 | */ 9 | public class GenericMethodInClass { 10 | 11 | class GenerateTest{ 12 | public void show_1(T t){ 13 | System.out.println(t.toString()); 14 | } 15 | 16 | //在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。 17 | @SuppressWarnings("hiding") //The type parameter T is hiding the type T 18 | public void show_2(T t){ 19 | System.out.println(t.toString()); 20 | } 21 | 22 | //在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。 23 | //由于泛型方法在声明的时候会声明泛型,因此即使在泛型类中并未声明泛型,编译器也能够正确识别泛型方法中识别的泛型。 24 | public void show_3(E t){ 25 | System.out.println(t.toString()); 26 | } 27 | 28 | } 29 | 30 | 31 | public static void main(String[] args) { 32 | GenericMethodInClass gmi = new GenericMethodInClass(); 33 | Apple apple = gmi.new Apple(); 34 | Person person = gmi.new Person(); 35 | GenerateTest generateTest = gmi.new GenerateTest(); 36 | 37 | //apple是Fruit的子类,所以这里可以 38 | generateTest.show_1(apple); 39 | //编译器会报错,因为泛型类型实参指定的是Fruit,而传入的实参类是Person 40 | //generateTest.show_1(person); 41 | 42 | //使用这两个方法都可以成功 43 | generateTest.show_2(apple); 44 | generateTest.show_2(person); 45 | 46 | //使用这两个方法也都可以成功 47 | generateTest.show_3(apple); 48 | generateTest.show_3(person); 49 | } 50 | 51 | class Fruit{ 52 | @Override 53 | public String toString() { 54 | return "fruit"; 55 | } 56 | } 57 | 58 | class Apple extends Fruit{ 59 | @Override 60 | public String toString() { 61 | return "apple"; 62 | } 63 | } 64 | 65 | class Person{ 66 | @Override 67 | public String toString() { 68 | return "Person"; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/Person.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | /** 3 | * 人 4 | * @author hepengju 5 | * 6 | */ 7 | class Person{ 8 | private String name; 9 | public Person(String name) {this.name = name;} 10 | public String getName() {return name;} 11 | public void setName(String name) {this.name = name;} 12 | @Override 13 | public String toString() { 14 | return "Person [name=" + name + "]"; 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/PersonComparator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * 人比较器 7 | * @author hepengju 8 | * 9 | */ 10 | public class PersonComparator implements Comparator{ 11 | @Override 12 | public int compare(Person o1, Person o2) { 13 | return o1.getName().compareTo(o2.getName()); 14 | } 15 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/PersonGeneric.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | public class PersonGeneric extends Generic{ 4 | 5 | public PersonGeneric(Person key) { 6 | super(key); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/StringGenerator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | /** 4 | * 子类指定泛型实现 5 | * 6 | * @author hepengju 7 | * 8 | */ 9 | public class StringGenerator extends Generic{ 10 | 11 | public StringGenerator(String key) { 12 | super(key); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/Student.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | /** 3 | * 学生 4 | * @author hepengju 5 | * 6 | */ 7 | public class Student extends Person{ 8 | private Integer age; 9 | public Student(String name, Integer age) { 10 | super(name); 11 | this.age = age; 12 | } 13 | public Integer getAge() {return age;} 14 | public void setAge(Integer age) {this.age = age;} 15 | @Override 16 | public String toString() { 17 | return "Student [age=" + age + ", getName()=" + getName() + "]"; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/StudentComparator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * 学生比较器 7 | * @author hepengju 8 | * 9 | */ 10 | public class StudentComparator implements Comparator{ 11 | @Override 12 | public int compare(Student o1, Student o2) { 13 | return o1.getName().compareTo(o2.getName()) == 0 ? o1.getAge().compareTo(o2.getAge()) : o1.getName().compareTo(o2.getName()); 14 | } 15 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new06_generic/_GenericReflect.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new06_generic; 2 | 3 | /** 4 | * 泛型信息的反射获取 5 | * 6 | *
TODO 7 | *
疑问: 为什么泛型信息在编译后的class文件中已经被擦除了,还能通过反射获得泛型信息呢? (难道是编译成class前的阶段就获得了?) 8 | *
9 | *
10 | *
11 | * 12 | * @author hepengju 13 | * 14 | */ 15 | public class _GenericReflect { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/A_Anno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation; 2 | 3 | import static java.lang.annotation.RetentionPolicy.SOURCE; 4 | 5 | import java.lang.annotation.Retention; 6 | 7 | /** 8 | * 简单注解 9 | * 10 | * @author hepengju 11 | * 12 | */ 13 | @Retention(SOURCE) 14 | @interface A_Anno{ 15 | String value() default ""; 16 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/B_Anno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.ElementType.TYPE; 5 | import static java.lang.annotation.RetentionPolicy.CLASS; 6 | 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | import com.hepengju.java05.new05_enum.WorkdayEnum; 11 | 12 | /** 13 | * 14 | * 简单注解, value为枚举 15 | * @author hepengju 16 | * 17 | */ 18 | @Retention(CLASS) 19 | @Target({ TYPE, METHOD }) 20 | public @interface B_Anno { 21 | WorkdayEnum[] value() default {}; 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/C_Anno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation; 2 | 3 | import static java.lang.annotation.ElementType.FIELD; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.ElementType.TYPE; 6 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 7 | 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | import com.hepengju.java05.new05_enum.WorkdayEnum; 12 | 13 | /** 14 | * 复杂注解 15 | * 16 | * @author hepengju 17 | * 18 | */ 19 | @Retention(RUNTIME) // 保留: 运行时 20 | @Target({TYPE,FIELD,METHOD}) // 限定: 类(含接口,注解,枚举),字段,方法 21 | public @interface C_Anno{ 22 | String name() default ""; // 添加属性 23 | int age() default 18; // 添加默认值 24 | boolean value() default true; // 特殊的value属性 25 | WorkdayEnum[] workdayArray() default {WorkdayEnum.SAT,WorkdayEnum.SUN}; // 工作日枚举数组 26 | } -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/P1_Anno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.ElementType.TYPE; 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | import java.lang.annotation.Inherited; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * 父类上的注解(可被继承) 13 | * 14 | * @author hepengju 15 | * 16 | */ 17 | @Retention(RUNTIME) 18 | @Target({ TYPE, METHOD }) 19 | @Inherited 20 | public @interface P1_Anno { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/P2_Anno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.ElementType.TYPE; 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 父类上的注解(不可被继承) 12 | * 13 | * @author hepengju 14 | * 15 | */ 16 | @Retention(RUNTIME) 17 | @Target({ TYPE, METHOD }) 18 | public @interface P2_Anno { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/Parent.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation; 2 | 3 | /** 4 | * 父类, 用于演示继承注解 5 | * 6 | * @author hepengju 7 | * 8 | */ 9 | @P1_Anno 10 | @P2_Anno 11 | public class Parent { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * @author hepengju 3 | * 4 | */ 5 | @A_Anno // 包上注解 6 | package com.hepengju.java05.new07_annotation; -------------------------------------------------------------------------------- /src/com/hepengju/java05/new07_annotation/spring/_SpringAnno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new07_annotation.spring; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * spring的常见注解 7 | * 8 | *
 9 |  * 基本注解: @Controller, @Service, @Repository, @Component
10 |  *
11 |  * spring4注解
12 |  *      * @Configuration        --> applicationContext.xml
13 |  *      * @Bean                 --> bean标签
14 |  *          - @Scope            --> scope属性, singleton/prototype
15 |  *          - @Lazy             --> 懒加载
16 |  *          - initMethod
17 |  *          - destoryMethod
18 |  *      * @ComponentScan        --> 
19 |  *          - value指定基础包, 对应base-package属性
20 |  *          - excludeFilters    --> context:exclude-filter
21 |  *          - includeFilters    --> context:include-filter, 需指定useDefaultFilters为false
22 |  *              * @Filter, 指定过滤方式(注解,指定类型,切点表达式,正则及自定义)及对应的值
23 |  *      * @Conditional          --> 按照条件在容器中添加bean
24 |  *          - Condition         --> 接口, matches方法
25 |  *      * @Import               --> 快速导入简单组件
26 |  *          - 传入组件全类名      --> id默认是组件的全类名
27 |  *          - ImportSelector    --> 返回需要导入的组件的全类名数组
28 |  *          - ImportBeanDefinitionRegistrar --> 自定义注册bean信息
29 |  *      *
30 |  *
31 |  *
32 |  *  给容器中添加bean
33 |  *      1. 包扫描 + 组件标注注解  --> 自己写的
34 |  *      2. @Bean                --> 导入第三方包里面的组件
35 |  *      3. @Import              --> 快速导入简单组件
36 |  *      4. 工厂bean              --> 框架整合 (Spring提供的FactoryBean, 默认获取到的是getObject创建的对象, 要获取工厂bean本身, 需要id前面加入&)
37 |  *
38 |  *  bean的生命周期: bean创建,初始化(创建完成并赋值好之后调用),销毁; 容器管理的; 可以自定义初始化和销毁方法
39 |  *      1. @Bean注解指定初始化和销毁方法名
40 |  *      2. 实现InitializingBean接口和DisposableBean接口
41 |  *      3. JSR250规范的@PostConstruct和@PreDestroy
42 |  *      4. BeanPostProcessor接口: bean的后置处理器, 初始化前后 
43 |  *
44 |  * 
45 | * 46 | */ 47 | public class _SpringAnno { 48 | 49 | @Test public void baseAnno(){} 50 | } 51 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new08_juc/_JUC.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new08_juc; 2 | 3 | /** 4 | * 5 | * java.util.concurrent: 在并发编程中很常用的实用工具类 6 | * 7 | *
 8 |  *  TODO
 9 |  * 
10 | * 11 | * @see 尚硅谷JUC视频教程 链接: https://pan.baidu.com/s/1brYNssetziG6RzdgUDUyxQ 提取码: 1tei 12 | * 13 | * @author hepengju 14 | * 15 | */ 16 | public class _JUC { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new08_juc/_TimeUnit.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new08_juc; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * 时间单位 9 | * 10 | * @author hepengju 11 | * 12 | */ 13 | public class _TimeUnit { 14 | 15 | /** 16 | * 时间单位转换 17 | */ 18 | @Test public void testToXxx() { 19 | // 1天: 24小时,86400秒 20 | long hours = TimeUnit.DAYS.toHours(1); 21 | long seconds = TimeUnit.DAYS.toSeconds(1); 22 | System.out.println(hours); // 24 23 | System.out.println(seconds); // 86400 24 | 25 | // 4000: 分钟,小时(截断取整) 26 | long minutes = TimeUnit.SECONDS.toMinutes(4000); 27 | hours = TimeUnit.SECONDS.toHours(4000); 28 | System.out.println(minutes); // 66 29 | System.out.println(hours); // 1 30 | } 31 | 32 | /** 33 | * 线程睡眠, 等待, 插入 34 | */ 35 | @Test public void testThread() throws InterruptedException { 36 | TimeUnit.SECONDS.sleep(3); // 睡眠3秒, 比"Thread.sleep(3000);"看起来更易读 37 | System.out.println("Over.."); 38 | 39 | //TimeUnit.SECONDS.timedWait(this, 3); 40 | //TimeUnit.SECONDS.timedJoin(Thread.currentThread(), 3); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new09_introspector/_Introspector.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new09_introspector; 2 | 3 | /** 4 | * 5 | * 内省(introspector) 6 | * 7 | *
 8 |  *  TODO
 9 |  * 
10 | * 11 | * @author hepengju 12 | * 13 | */ 14 | public class _Introspector { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new10_processBuilder/ExecUtil.java: -------------------------------------------------------------------------------- 1 | //package com.hepengju.java05.new10_processBuilder; 2 | // 3 | //import java.io.BufferedReader; 4 | //import java.io.IOException; 5 | //import java.io.InputStream; 6 | //import java.io.InputStreamReader; 7 | // 8 | //import org.slf4j.Logger; 9 | //import org.slf4j.LoggerFactory; 10 | // 11 | ///** 12 | // * 执行系统命令 13 | // * 14 | // * 15 | // *
注意死锁问题 16 | // *
解决: 只要主进程在waitfor之前,能不断处理缓冲区中的数据就可以 17 | // * 18 | // * @see 调用Process.waitfor导致的进程挂起 19 | // * 20 | // * @author he_pe 21 | // * 22 | // */ 23 | //public class ExecUtil { 24 | // 25 | // private static Logger logger = LoggerFactory.getLogger(ExecUtil.class); 26 | // 27 | // public static void execCommand(String command) { 28 | // logger.info("begin exec os command: " + command); 29 | // Process process; 30 | // try { 31 | // process = Runtime.getRuntime().exec(command); 32 | // 33 | // //开启新线程处理正常输出 34 | // new Thread(() -> { 35 | // try(InputStream inputStream = process.getInputStream(); 36 | // BufferedReader bufr = new BufferedReader(new InputStreamReader(inputStream));){ 37 | // String out = null; 38 | // while ((out = bufr.readLine()) != null) { 39 | // logger.info(out); 40 | // } 41 | // } catch (IOException e) { 42 | // e.printStackTrace(); 43 | // } 44 | // }).start(); 45 | // 46 | // //开启新线程处理错误输出 47 | // new Thread(() -> { 48 | // try(InputStream inputStream = process.getErrorStream(); 49 | // BufferedReader bufr = new BufferedReader(new InputStreamReader(inputStream));){ 50 | // String out = null; 51 | // while ((out = bufr.readLine()) != null) { 52 | // logger.info(out); 53 | // } 54 | // } catch (IOException e) { 55 | // e.printStackTrace(); 56 | // } 57 | // }).start(); 58 | // 59 | // 60 | // // 阻塞当前进程,直到命令结束 61 | // process.waitFor(); 62 | // 63 | // 64 | // // 不会阻塞进程,但是调用时如果没有完成会报错 65 | // if (process.exitValue() != 0) { 66 | // logger.error("exec os command failure: " + command); 67 | // } else { 68 | // logger.info("exec os command success: " + command); 69 | // } 70 | // } catch (IOException | InterruptedException e) { 71 | // logger.error("exec os command exception: " + command); 72 | // e.printStackTrace(); 73 | // } 74 | // } 75 | // 76 | // 77 | // 78 | //} 79 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/new11_other/_Other.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java05.new11_other; 2 | 3 | import java.util.Arrays; 4 | import java.util.Queue; 5 | import java.util.concurrent.ArrayBlockingQueue; 6 | 7 | import org.junit.Test; 8 | 9 | /** 10 | * JDK5的其他新特性 11 | * 12 | *
13 |  *  1. 支持%s %d等格式化输出
14 |  *  2. StringBuilder
15 |  *  3. Arrays工具类的toString,hashCode等
16 |  *  4. Queue
17 |  * 
18 | * 19 | * @author hepengju 20 | * 21 | */ 22 | public class _Other { 23 | 24 | /** 25 | * 1. 支持%s %d等格式化输出 26 | */ 27 | @Test public void testPrintf() { 28 | System.out.printf("my name is %s, age is %d","hepengju", 28); 29 | } 30 | 31 | /** 32 | * 2. StringBuilder 33 | * 34 | * 一个可变的字符序列。 35 | * 此类提供一个与 StringBuffer 兼容的 API,但不保证同步。 36 | * 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。 37 | * 如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。 38 | * 39 | * 主要操作是 append 和 insert 方法 40 | */ 41 | @Test public void testStringBuilder() { 42 | StringBuilder sb = new StringBuilder(); 43 | sb.append("I'm StringBuilder!") 44 | .append("\t") 45 | .append("I'm not thread safe, but faster than StringBuffer"); 46 | 47 | sb.insert(4, "the "); 48 | 49 | System.out.println(sb.toString()); 50 | } 51 | 52 | /** 53 | * 3. Arrays工具类的toString,hashCode等 54 | */ 55 | @Test public void testArrays() { 56 | //toString, hashCode 57 | int[] arr = {3,2,5,6,9,1,2}; 58 | Arrays.sort(arr); 59 | System.out.println(Arrays.toString(arr)); 60 | System.out.println(Arrays.hashCode(arr)); 61 | 62 | //deepToString, deepHashCode 63 | int[][] arr2 = {{1,2,3},{4,5,6}}; 64 | System.out.println(Arrays.toString(arr2)); 65 | System.out.println(Arrays.deepToString(arr2)); 66 | System.out.println(Arrays.hashCode(arr2)); 67 | System.out.println(Arrays.deepHashCode(arr2)); 68 | } 69 | 70 | /** 71 | * 4. Queue 72 | * 73 | * 抛出异常 返回特殊值 74 | * 插入 add(e) offer(e) 75 | * 移除 remove() poll() 76 | * 检查 element() peek() 77 | */ 78 | @Test public void testQueue() { 79 | Queue queue = new ArrayBlockingQueue<>(2); 80 | 81 | queue.add("xiaoming"); 82 | queue.add("xiaoming"); 83 | //queue.add("xiaoming"); //java.lang.IllegalStateException: Queue full 84 | 85 | boolean offer = queue.offer("xiaoming"); 86 | System.out.println(offer); // 返回false 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/com/hepengju/java05/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java5的新特性 3 | * 4 | *
    5 | *
  1. 自动拆装箱 autoboxing/unboxing 6 | *
  2. 可变参数 varargs 7 | *
  3. 增强for enhanceFor/foreach 8 | *
  4. 静态导入 staticImport 9 | *
  5. 枚举 enum 10 | *
  6. 泛型 generic 11 | *
  7. 注解 annotation 12 | *
  8. 并发编程工具 juc(java.util.concurrent) 13 | *
  9. 内省 introspector 14 | *
  10. 进程创建器 processBuilder 15 | *
  11. 其他杂项改进 16 | *
      17 | *
    • printf 支持%s %d等格式化输出 18 | *
    • StringBuilder 19 | *
    • Arrays工具类的toString,hashCode等 20 | *
    • Queue 21 | *
    22 | *
23 | * 24 | * @see New Features and Enhancements J2SE 5.0 25 | * 26 | * @author hepengju 27 | * 28 | */ 29 | package com.hepengju.java05; 30 | 31 | -------------------------------------------------------------------------------- /src/com/hepengju/java06/new02_dynamicCompile/_DynamicCompile.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java06.new02_dynamicCompile; 2 | 3 | import javax.tools.JavaCompiler; 4 | import javax.tools.ToolProvider; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * 动态编译 10 | * 11 | *
12 |  * 
13 |  *  场景:
14 |  *      * JSP页面
15 |  *      * 热部署/热加载: 
16 |  *          - spring-boot-devtools
17 |  *          - JRebel 
18 |  *          - OSGI 架构
19 |  *           
20 |  * 
21 | * 22 | * @see Java SE6调用动态编译 23 | * @see java的热部署和热加载 24 | * 25 | * @author hepengju 26 | * 27 | */ 28 | public class _DynamicCompile { 29 | 30 | /** 31 | * 动态编译示例01 32 | */ 33 | @SuppressWarnings("unused") 34 | @Test public void testDynamicCompile01() { 35 | JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/hepengju/java06/new12_overrideBug/_OverrideBug.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java06.new12_overrideBug; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 7 | *
 8 |  *    @Override是JDK5就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override 
 9 |  *    而JDK6修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现都可以加上@Override
10 |  * 
11 | * @author hepengju 12 | * 13 | */ 14 | public class _OverrideBug { 15 | 16 | @Test public void testOverride() { 17 | Thread t01 = new MyThread01(); 18 | t01.start(); // MyThread01 override method run of Thread 19 | 20 | Thread t02 = new Thread(new MyThread02()); 21 | t02.start(); // MyThread02 override method run of Runnable 22 | 23 | } 24 | 25 | class MyThread01 extends Thread{ 26 | @Override 27 | public void run() { 28 | System.out.println("MyThread01 override method run of Thread"); 29 | } 30 | 31 | } 32 | 33 | class MyThread02 implements Runnable{ 34 | @Override // jdk5此处编译不通过 35 | public void run() { 36 | System.out.println("MyThread02 override method run of Runnable"); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/hepengju/java06/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java6的新特性 3 | * 4 | *
    5 | *
  1. 对脚本语言的支持: javascript, ruby, groovy, python 6 | *
  2. 动态编译Compiler API 7 | *
  3. Console开发控制台程序 8 | *
  4. Desktop类/SystemTray类 9 | *
  5. STAX处理XML, JAXB2实现对象和XML之间的映射 10 | *
  6. 轻量级Http Server API 11 | *
  7. 插入式注解处理API 12 | *
  8. 嵌入式数据库Derby 13 | *
  9. Web服务元数据 14 | *
  10. Common Annotations 15 | *
  11. 更简单更强大的JAX-WS 16 | *
  12. Override注解的BUG 17 | *
  13. Jtable的排序与过滤 18 | *
19 | * 20 | * @see Java SE 6 Features and Enhancements 21 | * 22 | * @author hepengju 23 | * 24 | */ 25 | package com.hepengju.java06; -------------------------------------------------------------------------------- /src/com/hepengju/java07/new01_binaryLiteral/_BinaryLiteral.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new01_binaryLiteral; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 二进制字面量 7 | * 8 | *
 9 |  * 
10 |  *  进制字面量: 
11 |  *      * 二进制: 0b 或 0B 开头  --> 新支持
12 |  *      * 八进制: 0 开头
13 |  *      * 十六进制: 0x 或 0X 开头
14 |  *      
15 |  * 
16 | * 17 | * @author hepengju 18 | * 19 | */ 20 | public class _BinaryLiteral { 21 | 22 | /** 23 | * 十进制字面量 24 | */ 25 | @Test public void testOLiteral() { 26 | Integer m = 255; 27 | Integer n = 128; 28 | System.out.println("十进制: " + m); // 255 29 | System.out.println("十进制: " + n); // 128 30 | System.out.println("二进制: " + Integer.toBinaryString(m)); // 11111111 31 | System.out.println("二进制: " + Integer.toBinaryString(n)); // 10000000 32 | System.out.println("八进制: " + Integer.toOctalString(m)); // 377 33 | System.out.println("八进制: " + Integer.toOctalString(n)); // 200 34 | System.out.println("十六进制: " + Integer.toHexString(m)); // ff 35 | System.out.println("十六进制: " + Integer.toHexString(n)); // 80 36 | } 37 | 38 | /** 39 | * 二进制字面量: 0b 或 0B 开头 40 | */ 41 | @Test public void testBinaryLiteral() { 42 | int m = 0b11111111; 43 | int n = 0B10000000; 44 | System.out.println(m); // 255 45 | System.out.println(n); // 128 46 | } 47 | 48 | /** 49 | * 八进制字面量: 0 开头 50 | */ 51 | @Test public void testOctalLiteral() { 52 | int m = 0377; 53 | int n = 0200; 54 | System.out.println(m); // 255 55 | System.out.println(n); // 128 56 | } 57 | 58 | 59 | 60 | /** 61 | * 十六进制字面量: 0x 或 0X 开头 62 | */ 63 | @Test public void testHexLiteral() { 64 | int m = 0xff; 65 | int n = 0X80; 66 | System.out.println(m); // 255 67 | System.out.println(n); // 128 68 | } 69 | 70 | /** 71 | * 进制解析 72 | * 73 | *
{@link Integer#parseInt(String, int)} 支持2进制到36进制 74 | */ 75 | @Test public void testParse() { 76 | System.out.println(Integer.parseInt("11",2)); // 3 77 | System.out.println(Integer.parseInt("11",8)); // 9 78 | System.out.println(Integer.parseInt("11")); // 11 默认为10进制 79 | System.out.println(Integer.parseInt("11",16)); // 17 80 | 81 | System.out.println(Integer.parseInt("11",7)); // 8 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new02_numberUnderline/_NumberUnderline.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new02_numberUnderline; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 数字下划线 7 | * 8 | *
说明: 编译时编译器自己主动删除数字中的下划线 9 | * @author hepengju 10 | * 11 | */ 12 | public class _NumberUnderline { 13 | 14 | @Test public void testNumberUnderline() { 15 | int m = 100_0000; // 一百万 16 | int n = 1_0000_0000; // 一亿 17 | System.out.println(m); // 1000000 18 | System.out.println(n); // 100000000 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new03_switchString/_SwitchString.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new03_switchString; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * Switch对字符串的支持 10 | * 11 | *
12 |  *  说明: switch 语句中的变量类型可以是: byte、short、int、char 和 枚举
13 |  *       从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
14 |  * 
15 | * 16 | * @author hepengju 17 | * 18 | */ 19 | public class _SwitchString { 20 | 21 | @Test public void testSwitchString() { 22 | List list = Arrays.asList("孙悟空","猪八戒","唐玄奘","沙悟净","白骨精"); 23 | 24 | for (String name : list) { 25 | switch (name) { 26 | case "孙悟空": 27 | System.out.println("大师兄好样的"); 28 | break; 29 | case "猪八戒": 30 | System.out.println("二师兄喜欢美女,喜欢吃"); 31 | break; 32 | case "唐玄奘": 33 | System.out.println("我是师傅,听我的"); 34 | break; 35 | case "沙悟净": 36 | System.out.println("大师兄, 师傅被妖怪抓走啦"); 37 | break; 38 | default: 39 | System.out.println("我是谁...."); 40 | break; 41 | } 42 | } 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new04_genericInference/_GenericInference.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new04_genericInference; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * 泛型的类型推断 10 | * 11 | * @author hepengju 12 | * 13 | */ 14 | public class _GenericInference { 15 | 16 | @SuppressWarnings("unused") 17 | @Test public void testGenericInference() { 18 | List list01 = new ArrayList(); 19 | List list02 = new ArrayList<>(); // 后面的类型可以推断出来,可以省略不写 (必须要指定diamond操作符) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new07_twr/_TWR.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new07_twr; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | import java.sql.Connection; 6 | import java.sql.DriverManager; 7 | import java.sql.PreparedStatement; 8 | import java.sql.ResultSet; 9 | import java.sql.SQLException; 10 | 11 | import org.junit.Test; 12 | 13 | /** 14 | * 15 | * TWR(try-with-resource)语句 16 | * 17 | *
依赖: 实现AutoCloseable的接口 18 | *
另外: {@link Throwable} 添加 addSuppressed 方法和 getSuppressed 方法 19 | * 20 | * @author hepengju 21 | * 22 | */ 23 | public class _TWR { 24 | 25 | // JDBC的四大连接参数 26 | // private String className = "com.mysql.jdbc.Driver"; 27 | private String url = "jdbc:mysql://192.168.180.100:3306/oss6?useSSL=false"; 28 | private String username = "root"; 29 | private String password = "root"; 30 | 31 | /** 32 | * 放在try的小括号里面可以自动关闭, 并且更加安全 33 | */ 34 | @Test public void testTWR01() { 35 | try (Connection conn = DriverManager.getConnection(url, username, password); 36 | PreparedStatement pstmt = conn.prepareStatement("select * from z010_role"); 37 | ResultSet rst = pstmt.executeQuery()) { 38 | int columnCount = rst.getMetaData().getColumnCount(); 39 | while (rst.next()) { 40 | for (int i = 1; i <= columnCount; i++) { 41 | Object obj = rst.getObject(i); 42 | System.out.print(obj + "\t"); 43 | } 44 | System.out.println(); 45 | } 46 | } catch (SQLException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | /** 52 | * catch 可以捕获多个异常 53 | */ 54 | @Test public void testTWR02() { 55 | Class clazz = this.getClass(); 56 | try { 57 | Method method = clazz.getDeclaredMethod("show"); 58 | Object obj = method.invoke(this); 59 | System.out.println(obj); 60 | } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | 65 | public void show() { 66 | System.out.println("I'm show method"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new08_nio/_NIO.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new08_nio; 2 | 3 | import static java.nio.charset.StandardCharsets.UTF_8; 4 | import static java.util.stream.Collectors.toList; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.net.URISyntaxException; 9 | import java.nio.file.Files; 10 | import java.nio.file.Path; 11 | import java.nio.file.Paths; 12 | import java.util.List; 13 | 14 | import org.junit.Test; 15 | 16 | /** 17 | * NIO(new IO) 18 | * 19 | *
 20 |  *  说明: 
 21 |  *  主要:
 22 |  *      * bytebuffer
 23 |  *      * filechannel
 24 |  *      
 25 |  *      * Path  取代File
 26 |  *      * Paths 工具类,获取Path
 27 |  *      * Files 工具类的实用方法
 28 |  * 
29 | * @author hepengju 30 | * 31 | */ 32 | public class _NIO { 33 | 34 | /** 35 | * 把文件读取为字符串 36 | */ 37 | @Test public void testFiles() throws IOException { 38 | Path path = Paths.get("/Users/hepengju/HPJ/work/01_调度工具/调度工具-部署-何鹏举/readme.md"); 39 | String content = new String(Files.readAllBytes(path),UTF_8); 40 | System.out.println(content); 41 | 42 | // ## 文档说明 43 | // - 日期: 20180211 44 | // - 作者: 何鹏举 45 | // - 邮箱: he.pj@topcheer.com 46 | // - 简述: 对Perl版本的调度工具进行说明,并对代码予以分析与追加注释 47 | // ... 48 | 49 | } 50 | 51 | /** 52 | * 把文件读取每行进行处理 53 | */ 54 | @Test public void testFilesLines() throws IOException { 55 | Path path = Paths.get("/Users/hepengju/HPJ/work/01_调度工具/调度工具-部署-何鹏举/readme.md"); 56 | 57 | // 一次性读取完 58 | List allLines = Files.readAllLines(path); 59 | allLines.forEach(System.out::println); 60 | 61 | System.out.println("--------------------------"); 62 | 63 | // 流处理 64 | Files.lines(path).forEach(System.out::println); 65 | 66 | // ## 文档说明 67 | // - 日期: 20180211 68 | // - 作者: 何鹏举 69 | // - 邮箱: he.pj@topcheer.com 70 | // - 简述: 对Perl版本的调度工具进行说明,并对代码予以分析与追加注释 71 | // ... 72 | 73 | } 74 | 75 | 76 | 77 | /** 78 | * 遍历文件夹(java8新增) 79 | * 80 | * @see java.nio.file.Files.walk(Path, FileVisitOption...) 81 | */ 82 | @Test public void testFilesWalk() throws URISyntaxException, IOException { 83 | Path path = Paths.get("/Users/hepengju/HPJ"); 84 | List allNeedFile = Files.walk(path) 85 | .map(Path::toFile) 86 | .filter(f -> f.getName().endsWith(".md")) 87 | .filter(f -> f.getName().toLowerCase().equals(f.getName())) 88 | .filter(f -> f.length() > 0) 89 | .collect(toList()); 90 | 91 | allNeedFile.forEach(System.out::println); 92 | 93 | // /Users/hepengju/HPJ/team/GIT/ExcelVBAUtils/01_数据库设计工具/帮助手册/数据库设计工具.md 94 | // /Users/hepengju/HPJ/work/09_Jar包修改/mybatis/readme.md 95 | // /Users/hepengju/HPJ/work/09_Jar包修改/mybatisPlus/readme.md 96 | // /Users/hepengju/HPJ/work/01_调度工具/调度工具-部署-何鹏举/readme.md 97 | // /Users/hepengju/HPJ/work/01_调度工具/调度工具-部署-何鹏举/TBS/doc/readme.md 98 | // ... 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new09_forkjoin/ForkJoinCalculate.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new09_forkjoin; 2 | 3 | import java.util.concurrent.RecursiveTask; 4 | 5 | /** 6 | * fork/join计算类 7 | * 8 | *
继承 RecursiveTask(有返回值) 或 RecursiveAction(无返回值) 9 | * 10 | * @author hepengju 11 | * 12 | */ 13 | @SuppressWarnings("serial") 14 | public class ForkJoinCalculate extends RecursiveTask{ 15 | 16 | private long start; // 起始值 17 | private long end; // 结束值 18 | 19 | private static final long THRESHOLD = 10000; // 临界值 20 | 21 | 22 | public ForkJoinCalculate(long start, long end) { 23 | this.start = start; 24 | this.end = end; 25 | } 26 | 27 | @Override 28 | protected Long compute() { 29 | long length = end - start; 30 | 31 | // 小于临界值直接计算 32 | if (length <= THRESHOLD) { 33 | long sum = 0; 34 | for (long i = start; i <= end; i++) { 35 | sum += i; 36 | } 37 | return sum; 38 | } else { 39 | // 大于临界值, 拆分子任务计算然后合并 40 | long middle = (start + end) / 2; 41 | ForkJoinCalculate left = new ForkJoinCalculate(start, middle); 42 | left.fork(); 43 | 44 | ForkJoinCalculate right = new ForkJoinCalculate(middle + 1, end); 45 | right.fork(); 46 | 47 | return left.join() + right.join(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new09_forkjoin/_ForkJoin.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new09_forkjoin; 2 | 3 | import java.time.Duration; 4 | import java.time.Instant; 5 | import java.util.concurrent.ForkJoinPool; 6 | import java.util.concurrent.ForkJoinTask; 7 | import java.util.stream.LongStream; 8 | 9 | import org.junit.After; 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | 13 | /** 14 | * ForkJoin框架 15 | * 16 | *
17 |  * 
18 |  *  说明: 在必要的情况下,将一个大任务拆分(fork)为若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行(join)汇总
19 |  *       其采用"工作窃取"模式(work-stealing): 当执行新的任务时它可以将其拆分为更小的任务执行,并将它放在自己的队列中
20 |  *       
21 |  *  优势: 相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上. 在一般的线程池中,如果一个线程正在执行的任务
22 |  *       由于某些原因无法继续运行,那么该线程会处理等待状态. 而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而
23 |  *       无法继续运行,那么处理该问题的线程会主动寻找其他尚未运行的子问题来执行,这种方式减少了线程的等待时间,提高了性能
24 |  *  
25 |  *  相关类:
26 |  *      - ForkJoinPool     ForkJoin线程池
27 |  *      - RecursiveAction  递归行为(无返回值)
28 |  *      - RecursiveTask    递归任务(有返回值)
29 |  *         
30 |  *  备注: Java8中的StreamAPI的并行方法, 底层用的就是ForkJoin框架
31 |  *  
32 |  * 
33 | * 34 | * @see ForkJoinCalculate 35 | * @author hepengju 36 | * 37 | */ 38 | public class _ForkJoin { 39 | 40 | // 计算运行耗时 41 | private Instant begin; 42 | private Instant end; 43 | 44 | @Before public void before() { 45 | begin = Instant.now(); 46 | } 47 | 48 | @After public void after() { 49 | end = Instant.now(); 50 | System.out.printf("耗时(毫秒): %s", Duration.between(begin, end).toMillis()); 51 | } 52 | 53 | // for fork/join parallelStream 54 | //private final Long MAX_NUM = 1_0000_0000L; // 65 108 81 55 | //private final Long MAX_NUM = 10_0000_0000L; // 546 459 295 56 | //private final Long MAX_NUM = 100_0000_0000L; // 5154 3183 2192 57 | private final Long MAX_NUM = 1000_0000_0000L; // 51430 31436 21341 58 | 59 | 60 | 61 | /** 62 | * 普通for循环 63 | */ 64 | @Test public void testNormalFor() { // 此处发现一个东东, 这个方法的名字起名字为testFor, 某些时候执行会报错! 65 | long sum = 0; 66 | for (long i = 0; i <= MAX_NUM; i++) { 67 | sum += i; 68 | } 69 | System.out.println(sum); 70 | } 71 | 72 | /** 73 | * fork/join示例 74 | */ 75 | @Test public void testForkJoin() { 76 | ForkJoinPool pool = new ForkJoinPool(); 77 | ForkJoinTask task = new ForkJoinCalculate(0, MAX_NUM); 78 | Long sum = pool.invoke(task); 79 | System.out.println(sum); 80 | } 81 | 82 | /** 83 | * java8的StreamAPI 84 | */ 85 | @Test public void testStreamAPI() { 86 | long sum = LongStream.range(0, MAX_NUM).parallel().sum(); 87 | System.out.println(sum); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/new10/_Other.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java07.new10; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 其他新特性 7 | * 8 | *
 9 |  *  1. @SafeVarargs 注解
10 |  * 
11 |  * 
12 | * @author hepengju 13 | * 14 | */ 15 | public class _Other { 16 | 17 | @Test public void testSafeVarargs() { 18 | 19 | } 20 | 21 | // public static T getFirstVar(@SuppressWarnings("unchecked") T... args) { 22 | // @SuppressWarnings("unchecked") 23 | @SafeVarargs 24 | public static T getFirstVar(T... args) { 25 | return args.length > 0 ? args[0] : null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/com/hepengju/java07/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java7的新特性 3 | * 4 | *
    5 | *
  1. 二进制字面量 6 | *
  2. 数字变量对下划线的支持 7 | *
  3. switch对String的支持 8 | *
  4. 泛型的类型推断 9 | *
  5. 获取环境信息的工具方法 10 | *
  6. 安全的加减乘除 11 | *
  7. 异常处理的处理TWR 12 | *
  8. IO/NIO 13 | *
  9. ForkJoin框架 14 | *
  10. char之间的equals 15 | *
  11. Boolean类型反转,空指针安全,参与位运算 16 | *
17 | * 18 | * @see Java SE 7 Features and Enhancements 19 | * 20 | * @see Java7的新特性 21 | * @author hepengju 22 | * 23 | */ 24 | package com.hepengju.java07; -------------------------------------------------------------------------------- /src/com/hepengju/java08/new01_lambda/_Lambda.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new01_lambda; 2 | 3 | import java.util.Comparator; 4 | import java.util.TreeSet; 5 | import java.util.function.BinaryOperator; 6 | import java.util.function.Consumer; 7 | 8 | import org.junit.Test; 9 | 10 | /** 11 | * Lambda表达式 12 | * 13 | *
14 |  *  说明: lambda是一个匿名函数, 可以理解为一段可以传递的代码(像数据一样进行传递)
15 |  *  作用: 更简洁,更灵活,提升Java语言的表达能力
16 |  *  语法:
17 |  *      左侧: Lambda参数
18 |  *      中间: Lambda操作符 -> ,也称为箭头操作符或
19 |  *      右侧: Lambda体       ,即要执行的功能
20 |  *
21 |  *  其他: lambda表达式比匿名内部类更加节省内存空间(Java8的JVM内存结构发生变化)
22 |  * 
23 | * 24 | * @author hepengju 25 | * 26 | */ 27 | public class _Lambda { 28 | 29 | /** 30 | * 从匿名类到Lambda表达式的转变 31 | */ 32 | @Test public void testLambdaHelloWorld() { 33 | 34 | // 匿名类01 35 | new Thread(new Runnable() { 36 | @Override 37 | public void run() { 38 | System.out.println("Hello"); 39 | } 40 | }).start();; 41 | 42 | // lambda01 43 | new Thread(() -> System.out.println("Hello")).start(); 44 | 45 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 46 | // 匿名类02 47 | TreeSet ts01 = new TreeSet<>(new Comparator() { 48 | @Override 49 | public int compare(String o1, String o2) { 50 | return Integer.compare(o1.length(), o2.length()); 51 | } 52 | }); 53 | 54 | // lambda02 55 | TreeSet ts02 = new TreeSet<>((o1,o2) -> Integer.compare(o1.length(), o2.length())); 56 | 57 | ts01.add("aaa"); ts02.add("aaa"); 58 | ts01.add("bb"); ts02.add("bb"); 59 | ts01.add("z"); ts02.add("z"); 60 | System.out.println(ts01); // [z, bb, aaa] 61 | System.out.println(ts02); // [z, bb, aaa] 62 | } 63 | 64 | /** 65 | * lambda语法: 能省则省 66 | */ 67 | @SuppressWarnings("unused") 68 | @Test public void testLambdaSyntax() { 69 | // 语法 70 | BinaryOperator bo = (Integer x,Integer y) -> { 71 | return x+y; 72 | }; 73 | 74 | // 简化1: 由于类型推断(编译器javac根据上下文环境推断出类型), 可以省略参数的类型 75 | bo = (x,y) -> { 76 | return x+y; 77 | }; 78 | 79 | // 简化2: 当Lambda体只有一条语句的时候可以省略return和大括号{} 80 | bo = (x,y) -> x + y; 81 | 82 | // 简化3: 当参数只有一个时, 可以省略小括号 83 | Consumer fun = args -> System.out.println(args); 84 | 85 | // 简化4: 当参数个数为零时, 使用()即可 86 | Runnable r1 = () -> System.out.println("Hello Lambda"); 87 | 88 | // 简化5: 方法引用(下个新特性) 89 | Consumer fun02 = System.out::println; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new02_functionalInterface/_FunctionalInterface.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new02_functionalInterface; 2 | 3 | import java.util.function.Function; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * 函数式接口 9 | * 10 | *
11 |  *  定义: 只有一个抽象方法的接口
12 |  *  说明: Lambda表达式需要"函数式接口"的支持, 可以使用 @FunctionalInterface 注解修改,检查接口是否是函数式接口
13 |  *  
14 |  *  Java8内置的函数式接口
15 |  * 
16 |  *      四大核心函数式接口
17 |  *          Consumer   : 消费型接口   void accept(T t)
18 |  *          Supplier   : 供给型接口   T get()
19 |  *          Function : 函数型接口   R apply(T t)
20 |  *          Predicate  : 断言型接口   boolean test(T t)
21 |  * 
22 |  *      其他函数式接口
23 |  *          BiConsumer  : 消费两个, 无返回值
24 |  *          UnaryOperator : 一元操作符 (Function子接口, T与R是一种类型)
25 |  *          BiFunction: 消费两个, 返回一个
26 |  *          BinaryOperator: 二元操作符 (BiFunction子接口, T,U,R是一种类型)
27 |  *          
28 |  *          ToIntFunction, ToLongFunction, ToDoubleFunction: 给定T类型数据,返回int,long,double
29 |  *          IntFunction  , LongFunction  , DoubleFunction  : 给定int,long,double,返回R类型
30 |  *
31 |  *          IntPredicate, LongPredicate, DoublePredicate: 针对基本类型的断言型接口
32 |  *
33 |  *  作用: 编写方法当需要传递Lambda表达式时,不用再自定义函数式接口,直接使用内置的函数式接口即可
34 |  * 
35 | * 36 | * @see java.lang.FunctionalInterface 37 | * 38 | * @author hepengju 39 | * 40 | */ 41 | public class _FunctionalInterface { 42 | 43 | /** 44 | * 自定义一个函数式接口测试 45 | */ 46 | @Test public void testMyFunctionInterface() { 47 | String src = "I'm a Boy"; 48 | String tar01 = handleStr01(src, s -> s.toUpperCase()); 49 | String tar02 = handleStr01(src, s -> s.toLowerCase()); 50 | System.out.println(tar01); // I'M A BOY 51 | System.out.println(tar02); // i'm a boy 52 | } 53 | 54 | @FunctionalInterface 55 | interface MyFun { 56 | T getValue(T src); 57 | } 58 | 59 | private String handleStr01(String src, MyFun mf) { 60 | return mf.getValue(src); 61 | } 62 | 63 | /** 64 | * 使用jdk的函数式接口测试 65 | */ 66 | @Test public void testJdkFunctionInterface() { 67 | String src = "I'm a Boy"; 68 | String tar01 = handleStr02(src, s -> s.toUpperCase()); 69 | String tar02 = handleStr02(src, s -> s.toLowerCase()); 70 | System.out.println(tar01); // I'M A BOY 71 | System.out.println(tar02); // i'm a boy 72 | } 73 | 74 | private String handleStr02(String src,Function fun) { 75 | return fun.apply(src); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new03_methodReference/_MethodReference.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new03_methodReference; 2 | 3 | import java.io.PrintStream; 4 | import java.util.function.BiFunction; 5 | import java.util.function.BinaryOperator; 6 | import java.util.function.Consumer; 7 | import java.util.function.Function; 8 | 9 | import org.junit.Test; 10 | 11 | /** 12 | * 方法引用, 构造器引用, 数组引用 13 | * 14 | *
15 |  *  方法引用
16 |  *      说明: 当要传递给Lambda体的操作, 已经有实现的方法时可以使用操作符"::"进行方法引用
17 |  *      注意: 实现抽象方法的参数列表, 必须与方法引用方法的参数列表保持一致
18 |  *      分类:
19 |  *          对象::实例方法
20 |  *          类::静态方法
21 |  *          类::实例方法    --> 当需要引用方法的第一个参数是调用对象, 并且第二个参数是需要引用方法的参数(或无参数)时, 可使用 ClassName::methodName
22 |  *  
23 |  *  构造器引用: ClassName::new
24 |  *  数组引用:   Type[]::new
25 |  * 
26 | * 27 | * @author hepengju 28 | * 29 | */ 30 | public class _MethodReference { 31 | 32 | /** 33 | * 方法引用示例 34 | */ 35 | @SuppressWarnings("unused") 36 | @Test public void testMethodReference() { 37 | // 对象::实例方法 38 | PrintStream ps = System.out; 39 | Consumer con01 = x -> ps.println(x); 40 | Consumer con02 = ps::println; // 即 System.out::println 41 | 42 | // 类::静态方法 43 | BinaryOperator bo1 = (x,y) -> Math.pow(x,y); 44 | BinaryOperator bo2 = Math::pow; 45 | 46 | // 类::实例方法 47 | BiFunction bi01 = (x,y) -> x.equals(y); 48 | BiFunction bi02 = String::equals; 49 | } 50 | 51 | /** 52 | * 构造器引用 53 | */ 54 | @SuppressWarnings("unused") 55 | @Test public void testConstructorReference() { 56 | Function fun01 = n -> new Person(n); 57 | Function fun02 = Person::new; 58 | } 59 | 60 | /** 61 | * 数组引用 62 | */ 63 | @SuppressWarnings("unused") 64 | @Test public void testArrayReference() { 65 | Function fun01 = n -> new Integer[n]; 66 | Function fun02 = Integer[]::new; 67 | } 68 | 69 | class Person{ 70 | Integer age; 71 | 72 | public Person(Integer age) { 73 | super(); 74 | this.age = age; 75 | } 76 | 77 | public Integer getAge() { 78 | return age; 79 | } 80 | 81 | public void setAge(Integer age) { 82 | this.age = age; 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new04_streamAPI/Person.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new04_streamAPI; 2 | 3 | /** 4 | * 人 5 | * 6 | * @author hepengju 7 | * 8 | */ 9 | public class Person implements Comparable{ 10 | String name; 11 | String pyFirst; 12 | 13 | int age; 14 | double salary; 15 | 16 | public Person(String name, String pyFirst, int age, double salary) { 17 | super(); 18 | this.name = name; 19 | this.pyFirst = pyFirst; 20 | this.age = age; 21 | this.salary = salary; 22 | } 23 | 24 | 25 | @Override 26 | public int hashCode() { 27 | final int prime = 31; 28 | int result = 1; 29 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 30 | return result; 31 | } 32 | 33 | 34 | @Override 35 | public boolean equals(Object obj) { 36 | if (this == obj) 37 | return true; 38 | if (obj == null) 39 | return false; 40 | if (getClass() != obj.getClass()) 41 | return false; 42 | Person other = (Person) obj; 43 | if (name == null) { 44 | if (other.name != null) 45 | return false; 46 | } else if (!name.equals(other.name)) 47 | return false; 48 | return true; 49 | } 50 | 51 | 52 | public String getName() { 53 | return name; 54 | } 55 | public void setName(String name) { 56 | this.name = name; 57 | } 58 | public int getAge() { 59 | return age; 60 | } 61 | public void setAge(int age) { 62 | this.age = age; 63 | } 64 | public double getSalary() { 65 | return salary; 66 | } 67 | public void setSalary(double salary) { 68 | this.salary = salary; 69 | } 70 | 71 | public String getPyFirst() { 72 | return pyFirst; 73 | } 74 | 75 | 76 | public void setPyFirst(String pyFirst) { 77 | this.pyFirst = pyFirst; 78 | } 79 | 80 | 81 | @Override 82 | public int compareTo(Person o) { 83 | int nameCompare = this.name.compareTo(o.name); 84 | return nameCompare == 0 ? (int)(this.salary - o.salary) : nameCompare; 85 | } 86 | 87 | @Override 88 | public String toString() { 89 | return "Person [name=" + name + ", age=" + age + ", salary=" + salary + "]"; 90 | } 91 | 92 | } -------------------------------------------------------------------------------- /src/com/hepengju/java08/new05_optional/Car.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new05_optional; 2 | 3 | import java.util.Optional; 4 | 5 | /** 6 | * 汽车 7 | * 8 | * @author hepengju 9 | * 10 | */ 11 | public class Car { 12 | 13 | private String name; 14 | private Insurance insurance; 15 | private Optional oinsurance; 16 | 17 | public Car(String name) { 18 | super(); 19 | this.name = name; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public Insurance getInsurance() { 31 | return insurance; 32 | } 33 | 34 | public void setInsurance(Insurance insurance) { 35 | this.insurance = insurance; 36 | } 37 | 38 | public Optional getOinsurance() { 39 | return oinsurance; 40 | } 41 | 42 | public void setOinsurance(Optional oinsurance) { 43 | this.oinsurance = oinsurance; 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new05_optional/Insurance.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new05_optional; 2 | 3 | /** 4 | * 保险 5 | * 6 | * @author hepengju 7 | * 8 | */ 9 | public class Insurance { 10 | 11 | private String name; 12 | 13 | public Insurance(String name) { 14 | super(); 15 | this.name = name; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new05_optional/Person.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new05_optional; 2 | 3 | import java.util.Optional; 4 | 5 | public class Person { 6 | 7 | private String name; 8 | private Car car; 9 | private Optional ocar; 10 | 11 | 12 | public Person(String name) { 13 | this.name = name; 14 | } 15 | 16 | public String getName() { 17 | return this.name; 18 | } 19 | 20 | public Car getCar() { 21 | return car; 22 | } 23 | 24 | public void setCar(Car car) { 25 | this.car = car; 26 | } 27 | 28 | public void setName(String name) { 29 | this.name = name; 30 | } 31 | 32 | public Optional getOcar() { 33 | return ocar; 34 | } 35 | 36 | public void setOcar(Optional ocar) { 37 | this.ocar = ocar; 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /src/com/hepengju/java08/new06_interfaceMethod/_InterfaceMethod.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new06_interfaceMethod; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 接口方法 7 | * 8 | *
 9 |  *  说明: 接口中可以写"默认方法"和"静态方法"了
10 |  *  冲突: 
11 |  *      1.实现类的方法与接口默认方法相同时: 接口默认方法的"类优先"原则
12 |  *      2.实现两个接口的默认方法相同时, 必须重写此方法
13 |  *  
14 |  *  思考: 
15 |  *      1.为什么需要加入"默认方法"呢?
16 |  *          a) Iterable接口(Collection接口的父接口)想添加forEach方法,
17 |  *              由于其实现类有非常的多(jdk自身及第三方类库)都需要修改.
18 |  *              而这个方法的实现其实是很简单的,向接口中添加默认方法可以使用最小代价实现兼容性和代码复用
19 |  *          b) WindowListener 接口, WindowAdapter 适配器
20 |  *              之前设计接口, 另外提供xxxAdapter抽象类的空实现方法, 以便方便使用.
21 |  *              加入默认方法后, 接口本身就可以提供实现了, 不必再使用适配器
22 |  *              比如SpringMVC5的处理器拦截器 HandlerInterceptor 就添加了默认实现, 以便实现本接口的时候 @Overide 需要的方法就好
23 |  *               
24 |  *      2.为什么需要加入"静态方法"呢?
25 |  *          Collection, Collections 工具类
26 |  *          Path      , Paths 工具类
27 |  *          既然第一点已经加入默认方法,那就再加入静态方法使得接口和工具类统一在一起
28 |  *      
29 |  *      3.java9中接口也可以加入私有方法
30 |  *          由于多个默认方法或静态方法可能需要代码的复用抽取, 因此java9又加入了可以写私有方法
31 |  * 
32 | * 33 | * @author hepengju 34 | * 35 | */ 36 | public class _InterfaceMethod { 37 | 38 | /** 39 | * 测试默认方法和静态方法 40 | */ 41 | @Test public void testDefaultMethodAndStaticMethod() { 42 | MyInter.out("我是静态方法"); // 我是静态方法 43 | 44 | MyInter mi = s -> s + "**"; 45 | String src = "apply"; 46 | System.out.println(mi.apply(src)); // apply** 47 | System.out.println(mi.applyTwoTime(src)); // apply**** 48 | } 49 | 50 | @FunctionalInterface 51 | interface MyInter{ 52 | String apply(String src); 53 | 54 | // 默认方法 55 | default String applyTwoTime(String src) { 56 | String one = apply(src); 57 | String two = apply(one); 58 | return two; 59 | } 60 | 61 | // 静态方法 62 | static void out(String out) { 63 | System.out.println(out); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new07_collector/Person.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new07_collector; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * 人 7 | * 8 | * @author hepengju 9 | * 10 | */ 11 | public class Person implements Comparable{ 12 | private String name; 13 | private Integer age; 14 | private Double salary; 15 | 16 | public Person(String name, Integer age, Double salary) { 17 | super(); 18 | this.name = name; 19 | this.age = age; 20 | this.salary = salary; 21 | } 22 | 23 | 24 | @Override 25 | public int hashCode() { 26 | final int prime = 31; 27 | int result = 1; 28 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 29 | return result; 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | if (this == obj) 35 | return true; 36 | if (obj == null) 37 | return false; 38 | if (getClass() != obj.getClass()) 39 | return false; 40 | Person other = (Person) obj; 41 | if (name == null) { 42 | if (other.name != null) 43 | return false; 44 | } else if (!name.equals(other.name)) 45 | return false; 46 | return true; 47 | } 48 | 49 | 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | public void setName(String name) { 55 | this.name = name; 56 | } 57 | public Integer getAge() { 58 | return age; 59 | } 60 | public void setAge(Integer age) { 61 | this.age = age; 62 | } 63 | public Double getSalary() { 64 | return salary; 65 | } 66 | public void setSalary(Double salary) { 67 | this.salary = salary; 68 | } 69 | @Override 70 | public String toString() { 71 | return "Person [name=" + name + ", age=" + age + ", salary=" + salary + "]"; 72 | } 73 | 74 | @Override 75 | public int compareTo(Person o) { 76 | Comparator com = Comparator.nullsFirst(Comparator.comparing(Person::getName)); 77 | return com.compare(this,o); 78 | } 79 | 80 | 81 | } -------------------------------------------------------------------------------- /src/com/hepengju/java08/new08_comparator/Person.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new08_comparator; 2 | 3 | public class Person { 4 | 5 | private String name; 6 | private Integer age; 7 | private Double salary; 8 | 9 | 10 | public Person(String name, Integer age, Double salary) { 11 | super(); 12 | this.name = name; 13 | this.age = age; 14 | this.salary = salary; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | public Integer getAge() { 24 | return age; 25 | } 26 | public void setAge(Integer age) { 27 | this.age = age; 28 | } 29 | public Double getSalary() { 30 | return salary; 31 | } 32 | public void setSalary(Double salary) { 33 | this.salary = salary; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "Person [name=" + name + ", age=" + age + ", salary=" + salary + "]"; 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new08_comparator/_Comparator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new08_comparator; 2 | 3 | import static java.util.Comparator.comparing; 4 | import static java.util.Comparator.naturalOrder; 5 | import static java.util.Comparator.nullsLast; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Comparator; 9 | import java.util.List; 10 | 11 | import org.junit.Test; 12 | 13 | /** 14 | * 比较器: java8中提供了一系列默认方法和静态方法处理 Comparator 15 | * 16 | * @author hepengju 17 | */ 18 | public class _Comparator { 19 | 20 | /** 21 | * 排序 22 | */ 23 | @Test public void testComparator() { 24 | List personList = new ArrayList<>(); 25 | personList.add(new Person("hepengju", 28, 20000.0)); 26 | personList.add(new Person("lisi" , 44, 40000.0)); 27 | personList.add(new Person("wangwu" , 55, 50000.0)); 28 | personList.add(new Person("zhaoliu" , 66, 60000.0)); 29 | personList.add(new Person("zhangsan", 33, 33333.0)); 30 | personList.add(new Person("zhangsan", 23, 30000.0)); 31 | 32 | 33 | // 1. sort的参数为null时, 必须实现Comparable接口才行 34 | // personList.sort(null); 35 | 36 | // 2. 按照名字排序 37 | Comparator c1 = comparing(Person::getName); 38 | personList.sort(c1); 39 | 40 | // 3. 先按照名字排序, 名字一样再按照年龄排序, 年龄一样再按照薪资排序 41 | Comparator c2 = comparing(Person::getName).thenComparing(Person::getAge).thenComparing(Person::getSalary); 42 | personList.sort(c2); 43 | 44 | // 4. 处理所有空值问题(null都到最后) 45 | personList.add(null); 46 | personList.add(new Person(null, 33, 30000.0)); 47 | personList.add(new Person("zhangsan", null, 30000.0)); 48 | personList.add(new Person("zhangsan", 33, null)); 49 | personList.add(new Person(null, null, null)); 50 | 51 | Comparator c3 = nullsLast(comparing(Person::getName , nullsLast(naturalOrder())) 52 | .thenComparing(Person::getAge , nullsLast(naturalOrder())) 53 | .thenComparing(Person::getSalary, nullsLast(naturalOrder()))); 54 | personList.sort(c3); 55 | personList.forEach(System.out::println); 56 | 57 | /* 58 | * 结果如下: 59 | Person [name=hepengju, age=28, salary=20000.0] 60 | Person [name=lisi, age=44, salary=40000.0] 61 | Person [name=wangwu, age=55, salary=50000.0] 62 | Person [name=zhangsan, age=23, salary=30000.0] 63 | Person [name=zhangsan, age=33, salary=33333.0] 64 | Person [name=zhangsan, age=33, salary=null] 65 | Person [name=zhangsan, age=null, salary=30000.0] 66 | Person [name=zhaoliu, age=66, salary=60000.0] 67 | Person [name=null, age=33, salary=30000.0] 68 | Person [name=null, age=null, salary=null] 69 | null 70 | */ 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new09_iostream/tmp.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hepengju/java-new-features/7a7f17693580f588e926ffebc6ac83fee998ffe0/src/com/hepengju/java08/new09_iostream/tmp.txt -------------------------------------------------------------------------------- /src/com/hepengju/java08/new11_base64/Base64Util.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new11_base64; 2 | 3 | import java.util.Base64; 4 | 5 | /** 6 | * 简易的Base64加密和解密功能 7 | * 8 | * @author he_pe 2018-01-11 9 | */ 10 | public class Base64Util { 11 | 12 | // 加密 13 | public static String encode(String src) { 14 | return new String(Base64.getEncoder().encode(src.getBytes())); 15 | } 16 | 17 | // 解密 18 | public static String decode(String src) { 19 | return new String(Base64.getDecoder().decode(src.getBytes())); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new11_base64/_Base64.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new11_base64; 2 | 3 | import java.util.Base64; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Base64 9 | * 10 | *
11 |  *  Base64: Base64是一种基于64个可打印字符来表示二进制数据的表示方法(编码后的数据比原始数据略长,约为原来的4/3)
12 |  *  
13 |  *  为什么?
14 |  *      我们知道在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。
15 |  *      而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,
16 |  *      由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。
17 |  *      所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。
18 |  *      
19 |  *  使用场景:
20 |  *      * 证书: 特别是根证书,一般都是作Base64编码的, 因为它要在网上被很多人下载
21 |  *      * 电子邮件附件: 一般也作Base64编码的, 因为一个附件数据往往具有不可见字符
22 |  *      * 网页的小图片: 直接以Base64编码嵌入, 不用再链接请求消耗资源
23 |  *      * 迅雷下载链接
24 |  *      
25 |  *  说明: 在Java8中Base64编码已经成为Java类库的标准,Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:
26 |  *      * Basic: A-Za-z0-9+/
27 |  *      * URL: 由于标准的Basic编码可能会出现+和/, 在URL中就不能直接作为参数,所以又有一种“url safe” 的Base64编码,其实就是吧字符+和/分别变成-和_ 
28 |  *      * MIME: 输出每行不超过76字符,并且使用'\r'并跟随'\n'作为分割。编码输出最后没有行分割。
29 |  *          - MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型
30 |  *          
31 |  *  内部类:
32 |  *      * Base64.Decoder: 该类实现一个解码器,使用 Base64 编码来解码字节数据。
33 |  *      * Base64.Encoder: 该类实现一个编码器,使用 Base64 编码来编码字节数据。
34 |  *      
35 |  * 
36 | * 37 | * @see 维基百科Base64 38 | * @see 为什么要使用base64编码,有哪些情景需求? 39 | * @see Java8 Base64 40 | * 41 | * @author hepengju 42 | * 43 | */ 44 | public class _Base64 { 45 | 46 | /** 47 | * Java8的base64处理 48 | */ 49 | @Test public void testInJava8() { 50 | String src = "ossadmin"; 51 | System.out.println("原始: " + src); // 原始: ossadmin 52 | byte[] encode = Base64.getEncoder().encode(src.getBytes()); 53 | String tar = new String(encode); 54 | System.out.println("编码: " + tar); // 编码: b3NzYWRtaW4= 55 | 56 | byte[] decode = Base64.getDecoder().decode(tar.getBytes()); 57 | String res = new String(decode); 58 | System.out.println("解码: " + res); // 解码: ossadmin 59 | } 60 | 61 | /** 62 | * Java8前的base64处理 63 | * 64 | *
65 |      *  未公开内部类: BASE64Encoder/BASE64Decoder
66 |      *      sun.misc包下的BASE64Encoder及BASE64Decoder的sun.misc.BASE64Encoder/BASE64Decoder类
67 |      *      这个类是sun公司的内部方法,并没有在java api中公开过,不属于JDK标准库范畴,但在JDK中包含了该类,可以直接使用。
68 |      *      但是在Eclipse和MyEclipse中直接使用,却找不到该类
69 |      *  第三方工具: commons.codec下的Base64
70 |      *  
71 |      * 
72 | * 73 | * @see 解决Eclipse中无法直接使用Base64Encoder的问题 74 | */ 75 | @Test public void testBeforeJava8() { 76 | // 1.未公开内部类 77 | // BASE64Encoder encoder = new BASE64Encoder(); // sun.misc.BASE64Encoder 78 | // System.out.println(encoder.encode("ossadmin".getBytes()));//amF2YQ== 79 | 80 | // 2.commons-codec 81 | /* 82 | String src = "ossadmin"; 83 | System.out.println("原始: " + src); // 原始: ossadmin 84 | byte[] encode = org.apache.commons.codec.binary.Base64.encodeBase64(src.getBytes()); 85 | String tar = new String(encode); 86 | System.out.println("编码: " + tar); // 编码: b3NzYWRtaW4= 87 | 88 | byte[] dncodeBase64 = org.apache.commons.codec.binary.Base64.decodeBase64(tar.getBytes()); 89 | String res = new String(dncodeBase64); 90 | System.out.println("解码: " + res); // 解码: ossadmin 91 | */ 92 | } 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new12_completableFuture/Car.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new12_completableFuture; 2 | 3 | class Car { 4 | int id; 5 | int manufacturerId; 6 | String model; 7 | int year; 8 | float rating; 9 | 10 | public Car(int id, int manufacturerId, String model, int year) { 11 | this.id = id; 12 | this.manufacturerId = manufacturerId; 13 | this.model = model; 14 | this.year = year; 15 | } 16 | 17 | void setRating(float rating) { 18 | this.rating = rating; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "Car (id=" + id + ", manufacturerId=" + manufacturerId + ", model=" + model + ", year=" + year 24 | + ", rating=" + rating; 25 | } 26 | } -------------------------------------------------------------------------------- /src/com/hepengju/java08/new13_repeatalAnnotation/MyAnno.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new13_repeatalAnnotation; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.ElementType.TYPE; 5 | import static java.lang.annotation.ElementType.TYPE_PARAMETER; 6 | import static java.lang.annotation.ElementType.TYPE_USE; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | import java.lang.annotation.Repeatable; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * 15 | * 可重复的注解, 类型注解 16 | * 17 | * @author hepengju 18 | * 19 | */ 20 | 21 | @Repeatable(MyAnnos.class) 22 | @Retention(RUNTIME) 23 | @Target({ TYPE, METHOD,TYPE_PARAMETER, TYPE_USE }) 24 | public @interface MyAnno { 25 | String value(); 26 | } 27 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new13_repeatalAnnotation/MyAnnos.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new13_repeatalAnnotation; 2 | 3 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 4 | import static java.lang.annotation.ElementType.METHOD; 5 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 6 | 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 保存可重复注解的容器 12 | * 13 | * @author hepengju 14 | * 15 | */ 16 | @Retention(RUNTIME) 17 | @Target({ ANNOTATION_TYPE, METHOD }) 18 | public @interface MyAnnos { 19 | MyAnno[] value(); 20 | } 21 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new13_repeatalAnnotation/_RepeatAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new13_repeatalAnnotation; 2 | 3 | import java.lang.reflect.AnnotatedType; 4 | import java.lang.reflect.Method; 5 | import java.util.Arrays; 6 | 7 | import org.junit.Test; 8 | 9 | /** 10 | * 可重复注解, 类型注解 11 | * 12 | * @author hepengju 13 | * 14 | */ 15 | public class _RepeatAnnotation { 16 | 17 | /** 18 | * 可重复注解在标注一次和标注多次时的读取 19 | */ 20 | @Test public void testAnnotation() throws NoSuchMethodException, SecurityException { 21 | Class clazz = this.getClass(); 22 | Method method01 = clazz.getDeclaredMethod("show01", String.class); 23 | Method method02 = clazz.getDeclaredMethod("show02", String.class); 24 | 25 | // 1. 旧方法读取 26 | // 1.1 可重复注解标注一次时, 正常读取 27 | MyAnno anno01 = method01.getAnnotation(MyAnno.class); 28 | MyAnno anno02 = method02.getAnnotation(MyAnno.class); 29 | System.out.println(anno01); // @com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="three") 30 | System.out.println(anno02); // null 31 | 32 | // 1.2 可重复注解标注多次时, 编译后其实标注的是它的容器类 MyAnnos 33 | MyAnnos annos01 = method01.getAnnotation(MyAnnos.class); 34 | MyAnnos annos02 = method02.getAnnotation(MyAnnos.class); 35 | System.out.println(annos01); // null 36 | System.out.println(annos02); // @com.hepengju.java08.new08_repeatalAnnotation.MyAnnos(value={@com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="one"), @com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="two")}) 37 | 38 | // 2. 新方法读取 39 | // 2.1 可重复注解标注一次时, 也可以读到 40 | MyAnno[] as01 = method01.getAnnotationsByType(MyAnno.class); 41 | MyAnnos[] as02 = method01.getAnnotationsByType(MyAnnos.class); 42 | System.out.println(Arrays.toString(as01)); // [@com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="three")] 43 | System.out.println(Arrays.toString(as02)); // [] 44 | 45 | // 2.2 可重复注解标注多次时 46 | MyAnno[] as03 = method02.getAnnotationsByType(MyAnno.class); 47 | MyAnnos[] as04 = method02.getAnnotationsByType(MyAnnos.class); 48 | System.out.println(Arrays.toString(as03)); // [@com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="one"), @com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="two")] 49 | System.out.println(Arrays.toString(as04)); // [@com.hepengju.java08.new08_repeatalAnnotation.MyAnnos(value={@com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="one"), @com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="two")})] 50 | 51 | } 52 | 53 | /** 54 | * 类型参数读取 55 | */ 56 | @Test public void testTypeParameter() throws NoSuchMethodException, SecurityException { 57 | Class clazz = this.getClass(); 58 | Method method01 = clazz.getDeclaredMethod("show01", String.class); 59 | AnnotatedType[] types = method01.getAnnotatedParameterTypes(); 60 | for (AnnotatedType at : types) { 61 | MyAnno anno = at.getAnnotation(MyAnno.class); 62 | System.out.println(anno); // @com.hepengju.java08.new08_repeatalAnnotation.MyAnno(value="src") 63 | } 64 | } 65 | 66 | /** 67 | * 可重复注解标注一次的情况 68 | */ 69 | @MyAnno("three") 70 | public void show01(@MyAnno("src")String src) { 71 | @MyAnno("src")int i = 10; 72 | System.out.println(i + ": " + src); 73 | } 74 | 75 | /** 76 | * 可重复注解标注多次的情况 77 | */ 78 | @MyAnno("one") 79 | @MyAnno("two") 80 | public void show02(@MyAnno("src")String src) { 81 | @MyAnno("src")int i = 10; 82 | System.out.println(i + ": " + src); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new14_parameterName/_ParameterName.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new14_parameterName; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Parameter; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * 参数名字 10 | * 11 | *
12 |  *  说明: Java8可以通过设置使得编译后的class文件中保留参数名字,并通过反射获取
13 |  *  设置:
14 |  *      * javac -parameters
15 |  *      * Eclipse: 
16 |  *          - 全局设置: Preferences --> Java --> Compiler --> 勾选 Store information about method parameters(usable via reflection)
17 |  *          - 工程设置: 工程右键 --> Properties --> Java Compiler --> 勾选 Store information about method parameters(usable via reflection)
18 |  *      * maven: 
19 |  *          
20 |  *              org.apache.maven.plugins
21 |  *              maven-compiler-plugin
22 |  *              3.3
23 |  *              
24 |  *                  
25 |  *                      -parameters
26 |  *                  
27 |  *              
28 |  *          
29 |  *          
30 |  *  疑问: TODO 
31 |  *       SpringMVC中的Controller中不加 @RequestParam 且不开启编译保留参数时,它也可以通过反射获取到,其原理是什么? 
32 |  *       MyBatis就必须开启编译保留参数才可以省略Mapper接口方法参数上的 @Param
33 |  * 
34 | * 35 | * @author hepengju 36 | * 37 | */ 38 | public class _ParameterName { 39 | 40 | /** 41 | * 反射获取参数名字 42 | */ 43 | @Test public void testGetParameterName() throws NoSuchMethodException, SecurityException { 44 | Method method = this.getClass().getMethod("show", String.class, int.class); 45 | Parameter[] parameters = method.getParameters(); 46 | for (Parameter para : parameters) { 47 | System.out.println(para.getName()); 48 | // 未开: arg0 arg1 49 | // 开启: sql num 50 | } 51 | } 52 | 53 | 54 | 55 | public void show(String sql,int num) { 56 | System.out.println(sql + ":" + num); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/new20_other/_Other.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java08.new20_other; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 其他改进 7 | * 8 | *
 9 |  *  HashMap数据结构的改善
10 |  *      之前: 数组 + 链表
11 |  *      现在: 数组 + 链表 + 红黑树
12 |  * 
13 | * 14 | * @author hepengju 15 | */ 16 | 17 | public class _Other { 18 | 19 | /** 20 | * char和unicode的最值 21 | * 22 | *
23 |      *  char   : min[0], max[65535]
24 |      *  unicode: min[0], max[1114111]
25 |      * 
26 | */ 27 | @Test public void printMinMax() { 28 | System.out.printf("char : min[%d], max[%d]", (int)Character.MIN_VALUE, (int)Character.MAX_VALUE); 29 | System.out.println(); 30 | System.out.printf("unicode: min[%d], max[%d]", Character.MIN_CODE_POINT,Character.MAX_CODE_POINT); 31 | } 32 | 33 | /** 34 | * 打印所有char字符 35 | */ 36 | @Test public void printAllChar() { 37 | System.out.println("all char: " + (Character.MAX_VALUE - Character.MIN_VALUE)); 38 | for (char c = Character.MIN_VALUE; c < Character.MAX_VALUE; c++) { 39 | System.out.print(Character.toString(c) + ","); 40 | if(c % 100 == 0) System.out.println(); 41 | } 42 | } 43 | 44 | /** 45 | * 打印所有Unicode字符 46 | */ 47 | @Test public void printAllUnicode() { 48 | System.out.println("all unicode: " + (Character.MAX_CODE_POINT - Character.MIN_CODE_POINT)); 49 | for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) { 50 | System.out.print(Character.toString(i) + ","); 51 | if(i % 100 == 0) System.out.println(); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/com/hepengju/java08/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java8的新特性 3 | * 4 | *
    5 | *
  1. Lambda表达式 6 | *
  2. 函数式接口 7 | *
  3. 方法引用, 构造器引用(包括数组的构造器引用) 8 | *
  4. Stream API 9 | *
  5. 接口中的默认方法与静态方法 10 | *
  6. 新日期时间API 11 | *
  7. Optional类 12 | *
  8. 重复注解与类型注解 13 | *
  9. 参数名字 14 | *
  10. Map数据结构改进 15 | *
  11. Base64 16 | *
  12. IO流处理 17 | *
  13. 比较器 18 | *
  14. 并发增强 19 | *
  15. JavaFX 20 | *
  16. JavaScript引擎-Nashorn 21 | *
  17. 其他杂项改进 22 | *
      23 | *
    • 字符串 24 | *
    • 数字 25 | *
    • 集合 26 | *
    • Collections 27 | *
    28 | *
29 | * 30 | * @see What's New in JDK 8 31 | * 32 | * @author hepengju 33 | * 34 | */ 35 | package com.hepengju.java08; -------------------------------------------------------------------------------- /src/com/hepengju/java09/new01_jigsaw/module_01/_Person.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new01_jigsaw.module_01; 2 | 3 | /** 4 | * 5 | * @author WGR 6 | * 7 | */ 8 | public class _Person { 9 | 10 | private String name; 11 | private int age; 12 | 13 | 14 | 15 | public _Person() { 16 | super(); 17 | } 18 | 19 | public _Person(String name, int age) { 20 | super(); 21 | this.name = name; 22 | this.age = age; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public int getAge() { 34 | return age; 35 | } 36 | 37 | public void setAge(int age) { 38 | this.age = age; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "Person{" + 44 | "name='" + name + '\'' + 45 | ", age=" + age + 46 | '}'; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new01_jigsaw/module_02/_Module.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new01_jigsaw.module_02; 2 | 3 | import com.hepengju.java09.new01_jigsaw.module_01._Person; 4 | 5 | /** 6 | * 对模块化进行测试 7 | * 8 | * @author WGR 9 | * 10 | */ 11 | public class _Module { 12 | 13 | public void testModule() { 14 | 15 | _Person p = new _Person("Tom",12); 16 | System.out.println(p); 17 | 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new02_jshell/_Jshell.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new02_jshell; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * Java9拥有 REPL工具:Jshell 7 | * 8 | *
 9 |  *  设计理念:即写即得
10 |  *  实现目标:
11 |  *         * 利用jShell在没有创建类的情况下直接声明变量,计算表达式,执行语句。
12 |  *         * 可以从文件中加载语句或者将语句保存到文件中。
13 |  *         * 可以是tab键进行自动补全和自动添加分号。   
14 |  *  使用举例:
15 |  *         * 基本使用
16 |  *         * 导入指定的包
17 |  *         * 默认已经导入如下的所有包
18 |  *         * 只需按下Tab键,就能自动补全代码
19 |  *         * 列出当前session里所有有效的代码片段
20 |  *         * 使用外部代码编辑器来编写Java代码
21 |  *         * 使用/open命令调     
22 |  *  
23 |  * 
24 | * 25 | * @author WGR 26 | * 27 | */ 28 | public class _Jshell { 29 | 30 | /** 31 | * 调用Jshell 32 | */ 33 | @Test 34 | public void testJshell() { 35 | 36 | /*jshell> System.out.println("hello world"); 37 | hello world 38 | 39 | jshell> int i =10; 40 | i ==> 10 41 | jshell> int j =20; 42 | j ==> 20 43 | jshell> int k = i + j; 44 | k ==> 30 45 | jshell> System.out.println(k); 46 | 30 47 | jshell> public void add(int a,int b,int c){System.out.println(a + b +c);} 48 | | 已创建 方法 add(int,int,int) 49 | jshell> add(10,20,30); 50 | 60 51 | jshell> /imports 52 | | import java.io.* 53 | | import java.math.* 54 | | import java.net.* 55 | | import java.nio.file.* 56 | | import java.util.* 57 | | import java.util.concurrent.* 58 | | import java.util.function.* 59 | | import java.util.prefs.* 60 | | import java.util.regex.* 61 | | import java.util.stream.* 62 | 63 | jshell> /list 64 | 65 | 1 : System.out.println("hello world"); 66 | 2 : int i =10; 67 | 3 : int j =20; 68 | 4 : int k = i + j; 69 | 5 : System.out.println(k); 70 | 6 : public void add(int i,int j){} 71 | 7 : public void add(int a,int b,int c){System.out.println(a + b +c);} 72 | 8 : add(10,20,30); 73 | 74 | jshell> /open E:\workspaceide\HelloWorld.java 75 | Javad 新特性! 76 | jshell> 77 | */ 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new03_interface/_Interface.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new03_interface; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 接口的私有方法 7 | * 8 | *
 9 |  * 
10 |  *  说明:方法的访问权限修饰符都可以声明为private的了,此时方法将不会成为你对外暴露的API的一部分。
11 |  *  
12 |  * 
13 | * 14 | * @author WGR 15 | * 16 | */ 17 | interface MyInterface{ 18 | 19 | //jdk 7 : 只能声明全局常量(public static final)和抽象方法(public abstract) 20 | void method1(); 21 | 22 | // jdk 8 : 声明静态方法 和 默认方法 23 | public static void method2(){ 24 | System.out.println("method2"); 25 | } 26 | 27 | default void method3(){ 28 | System.out.println("method3"); 29 | method4(); 30 | } 31 | 32 | //jdk 9 : 声明私有方法 33 | private void method4(){ 34 | System.out.println("私有方法"); 35 | } 36 | 37 | 38 | } 39 | 40 | class MyInterfaceImpl implements MyInterface{ 41 | 42 | @Override 43 | public void method1() { 44 | System.out.println("实现接口中的抽象方法method1()"); 45 | } 46 | } 47 | 48 | public class _Interface { 49 | 50 | /** 51 | * 不能直接调用接口的私有方法 52 | */ 53 | @Test 54 | public void testInterface() { 55 | MyInterfaceImpl impl = new MyInterfaceImpl(); 56 | impl.method3(); //method3 私有方法 57 | 58 | // impl.method4(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new04_diamondoperator/_DiamondOperator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new04_diamondoperator; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * 钻石操作符 10 | * 11 | *
12 |  *  说明:
13 |  *      * Java7给出的钻石操作符使我们编写代码更简单了。
14 |  *      * Java7中钻石操作符不允许在匿名类上使用,但在Java9中改善了这一情况,允许钻石操作符在匿名类上使用。
15 |  * 
16 | * 17 | * @author WGR 18 | * 19 | */ 20 | public class _DiamondOperator { 21 | 22 | /** 23 | * set相当于创建一个继承于HashSet的匿名子类的对象 24 | */ 25 | @SuppressWarnings("serial") 26 | @Test 27 | public void diamondOperator(){ 28 | 29 | Set set = new HashSet<>(){};//编译通过 30 | set.add("MM"); 31 | set.add("JJ"); 32 | set.add("GG"); 33 | set.add("DD"); 34 | 35 | for(String s : set){ 36 | System.out.println(s); 37 | } 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new05_twr/_TWR.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new05_twr; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | import java.io.OutputStreamWriter; 6 | 7 | import org.junit.Test; 8 | 9 | /** 10 | * TWR(try-with-resource)语句 11 | * 12 | *
13 |  *  如果一个资源被final或者等效于final变量引用,则在不需要声明一个新的变量的情况下,
14 |  *  try-with-resources就可以管理这个资源。
15 |  * 
16 | * 17 | * @author WGR 18 | * 19 | */ 20 | public class _TWR { 21 | 22 | /** 23 | * java9 中:可以在try()中调用已经实例化的资源对象 24 | * 直接在try括号中直接写入 变量就好,如果有多个流,就用分号隔开 25 | */ 26 | @Test 27 | public void testTWR3(){ 28 | InputStreamReader reader = new InputStreamReader(System.in); 29 | OutputStreamWriter writer = new OutputStreamWriter(System.out); 30 | try(reader;writer){ 31 | //此时的reader是final的,不可再被赋值 32 | //reader = null; 33 | reader.read(); 34 | }catch(IOException e){ 35 | e.printStackTrace(); 36 | } 37 | } 38 | 39 | 40 | /** 41 | * java8中:要求资源对象的实例化,必须放在try的一对()内完成。 42 | */ 43 | @Test 44 | public void testTWR2(){ 45 | try(InputStreamReader reader = new InputStreamReader(System.in)){ 46 | reader.read(); 47 | }catch(IOException e){ 48 | e.printStackTrace(); 49 | } //不用显式的处理资源的关闭 50 | } 51 | 52 | /** 53 | * java8之前,习惯于这样处理资源的关闭: 54 | */ 55 | @Test 56 | public void testTWR1(){ 57 | 58 | InputStreamReader reader = null; 59 | 60 | try{ 61 | reader = new InputStreamReader(System.in); 62 | reader.read(); 63 | }catch (IOException e){ 64 | e.printStackTrace(); 65 | }finally{ 66 | //资源的关闭操作 67 | if(reader != null){ 68 | try { 69 | reader.close(); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } 74 | } 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new06_collection/_Collection.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new06_collection; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.HashMap; 7 | import java.util.HashSet; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | import org.junit.Test; 13 | 14 | /** 15 | * 不可变集合工厂方法 16 | * 17 | *
18 |  *  说明:
19 |  *        * Java9增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合。
20 |  * 
21 | * 22 | * @author WGR 23 | * 24 | */ 25 | public class _Collection { 26 | 27 | /** 28 | * jdk9 中:创建一个只读特点的集合 29 | * 创建的集合,使用add都会报错:UnsupportedOperationException 30 | */ 31 | @SuppressWarnings("unused") 32 | @Test 33 | public void testCollection2(){ 34 | List list = List.of(1, 2, 3); 35 | list.forEach(System.out::println); // 1 2 3 36 | 37 | Set set = Set.of(2, 3, 4); 38 | set.forEach(System.out::println); // 2 3 4 39 | 40 | //创建只读集合的方式一: 41 | Map map = Map.of("Tom", 23, "Jerry", 22, "Lilei", 12, "HanMeimei", 18); 42 | 43 | //创建只读集合的方式二: 44 | Map map1 = Map.ofEntries(Map.entry("Tom", 23), Map.entry("Jerry", 21)); 45 | 46 | System.out.println(map1); // {Tom=23, Jerry=21} 47 | 48 | } 49 | 50 | /** 51 | * jdk 8 以及之前:创建一个只读特点的集合 52 | */ 53 | @SuppressWarnings({ "serial", "unused" }) 54 | @Test 55 | public void testCollection1(){ 56 | List list = new ArrayList<>(); 57 | list.add("Tom"); 58 | list.add("Jerry"); 59 | list.add("Lilei"); 60 | list.add("HanMeimei"); 61 | 62 | //调用Collections中的方法,将list变为只读的 63 | List newList = Collections.unmodifiableList(list); 64 | //newList.add("Tim");//不能执行,否则报异常 65 | //遍历:jdk 8 66 | newList.forEach(System.out::println); 67 | 68 | List list1 = Collections.unmodifiableList(Arrays.asList(1, 2, 3)); 69 | 70 | Set set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(1, 2, 3))); 71 | 72 | Map map = Collections.unmodifiableMap(new HashMap<>() { 73 | { 74 | put("Tom", 78); 75 | put("Jerry", 88); 76 | put("Tim", 68); 77 | } 78 | }); 79 | 80 | map.forEach((k,v) -> System.out.println(k + ":" + v)); 81 | } 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new07_stream/_Stream.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new07_stream; 2 | 3 | import java.util.stream.Stream; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Java9对Stream流的增强 9 | * 10 | *
11 |  *  新增流的方法:
12 |  *                * 引入ofNullable方法
13 |  *                * 新增takewhile和dropwhile方法
14 |  *                * iterate(种子 、判定器 、单目运算)的有限迭代
15 |  * 
16 | * 17 | * @author WGR 18 | * 19 | */ 20 | 21 | public class _Stream { 22 | 23 | /** 24 | * 新增方法iterate(种子 、判定器 、单目运算)的有限迭代 25 | * iterate(T seed, Predicate hasNext, UnaryOperator next) 26 | */ 27 | @Test 28 | public void testIterate() { 29 | //没有新方法时,需要添加limit进行限制 30 | Stream stream1 = Stream.iterate(1, t -> (2 * t) + 1); 31 | stream1.limit(10).forEach(System.out::println); 32 | 33 | //有限的迭代 34 | Stream stream2 = Stream.iterate(1, t -> t < 1000, t -> (2 * t) + 1); 35 | stream2.forEach(System.out::println); 36 | } 37 | 38 | 39 | /** 40 | * 新方法,dropWhile 41 | * 从流中一直获取元素,遇到真的元素就drop,一旦遇到假的,就取剩下部分。 42 | */ 43 | @Test 44 | public void testDropWhile() { 45 | Stream stream1 = Stream.of(3, 9, 20, 22, 40, 7); 46 | Stream stream3 = stream1.dropWhile(t -> t % 2 != 0); 47 | stream3.forEach(System.out::println); // 20 22 40 7 48 | 49 | } 50 | 51 | 52 | /** 53 | * 新方法,takeWhile 54 | * 从流中一直获取判定器为真的元素, 一旦遇到元素为假, 就终止处理。 55 | */ 56 | @Test 57 | public void testTakeWhile() { 58 | Stream stream1 = Stream.of(3, 9, 20, 22, 40, 7); 59 | Stream stream2 = stream1.takeWhile(t -> t % 2 != 0); 60 | stream2.forEach(System.out::println); // 3 9 61 | 62 | } 63 | 64 | 65 | /** 66 | * 引入ofNullable方法,避免空指针异常 67 | */ 68 | @Test 69 | public void testOfNullable() { 70 | //传入null会被解析为是一个数组对象, 会进一步访问它的长度信息 71 | //Stream stream3 = Stream.of(null); 72 | //stream3.forEach(System.out::println); 73 | 74 | Stream stream3 = Stream.ofNullable(null); 75 | stream3.forEach(System.out::println); 76 | 77 | 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new08_httpclient/_HttpClient.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new08_httpclient; 2 | 3 | import java.io.IOException; 4 | import java.net.URI; 5 | import java.net.http.HttpClient; 6 | import java.net.http.HttpRequest; 7 | import java.net.http.HttpResponse; 8 | 9 | import org.junit.Test; 10 | 11 | //import jdk.incubator.http.HttpClient; 12 | //import jdk.incubator.http.HttpRequest; 13 | //import jdk.incubator.http.HttpResponse; 14 | 15 | //说明:JDK9中HttpClient是要引用模块的,由于改成Maven项目,统一用JDK11,这里只做演示。 16 | 17 | /** 18 | * 全新的Http客户端API 19 | * 20 | *
21 |  * 
22 |  *  说明:
23 |  *      * 提供了一个新的HTTP客户端(HttpClient),它将替代仅适用于blocking模式的HttpURLConnection。
24 |  *      * 提供对WebSocket和HTTP/2的支持,可以从jdk.incubator.httpclient模块中获取。
25 |  *      * 在Java 11中又再次升级,处于为正式可用状态。
26 |  *  
27 |  *  Java11的变化: 
28 |  *      * 从java9的jdk.incubator.httpclient模块迁移到java.net.http模块,包名由jdk.incubator.http改为java.net.http
29 |  *      * 原来的诸如HttpResponse.BodyHandler.asString()方法变更为HttpResponse.BodyHandlers.ofString(),
30 |  *        变化一为BodyHandler改为BodyHandlers,变化二为asXXX()之类的方法改为ofXXX(),由as改为of
31 |  * 
32 | * 33 | * @see Java11新特性之HttpClient小试牛刀 34 | * 35 | * @author WGR 36 | * 37 | */ 38 | public class _HttpClient { 39 | 40 | /** 41 | * 使用 HttpClient替换原有的HttpURLConnection 42 | */ 43 | @Test public void testHttpClient() { 44 | try { 45 | HttpClient client = HttpClient.newHttpClient(); 46 | HttpRequest req = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).GET().build(); 47 | HttpResponse response = null; 48 | //response = client.send(req, HttpResponse.BodyHandler.asString()); 49 | response = client.send(req, HttpResponse.BodyHandlers.ofString()); 50 | System.out.println(response.statusCode()); //200 51 | System.out.println(response.version().name()); //HTTP_1_1 52 | System.out.println(response.body()); //输出页面的内容 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } catch (InterruptedException e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new09_jsonAPI/_JsonAPI.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new09_jsonAPI; 2 | 3 | /** 4 | * 轻量级JSON API 5 | * 6 | * 一个标准化和轻量级的JSON API被许多java开发人员所青睐。但是由于资金问题无法在Java 9中见到。 7 | * 8 | * @author WGR 9 | * 10 | */ 11 | public class _JsonAPI { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_CompactStrings.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | 4 | 5 | /** 6 | * String底层存储结构更换 7 | * 8 | *
 9 |  *  说明:
10 |  *      * java8之前 String的底层结构类型都是 char[] ,但是java9 就替换成 byte[] 这样来讲,更节省了空间和提高了性能。
11 |  * 
12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _CompactStrings { 17 | 18 | //@Stable 19 | //private final byte[] value; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_JIT.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * java的动态编译器(JIT) 5 | *
 6 |  *  说明:
 7 |  *        * JIT(Just-in-time)编译器可以在运行时将热点编译成本地代码,速度很快。
 8 |  *        * 虽然仍处于试验阶段,但这个功能使得Java应用在被虚拟机启动之前能够先将Java类编译为原生代码。
 9 |  *  目的:          
10 |  *        * 此功能旨在改进小型和大型应用程序的启动时间,同时对峰值性能的影响很小。
11 |  *            
12 |  * @see 
13 |  * @see       
14 |  * 
15 |  * 
16 | * 17 | * @author WGR 18 | * 19 | */ 20 | public class _JIT { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_JavaDoc.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * javadoc的html5支持(添加搜索框) 5 | * 6 | *
 7 |  *  java 8:
 8 |  *            * 生成的java帮助文档是在HTML4中,而HTML4已经是很久的标准了。
 9 |  *  java 9:          
10 |  *            * javadoc的输出,现在符合兼容HTML5标准。(多了一个搜索框)
11 |  *            
12 |  * @see 
13 |  * @see  
14 |  *      
15 |  * 
16 | * 17 | * @author WGR 18 | * 19 | */ 20 | public class _JavaDoc { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_Locking.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * 改善锁的竞争机制 5 | * 6 | *
 7 |  *  使用说明:锁争用是限制许多Java多线程应用性能的瓶颈。
 8 |  *            新的机制在改善Java对象监视器的性能方面已经得到了多种基准(benchmark)的验证, 其中包括Volano. 
 9 |  * 
10 | * 11 | * @see
12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _Locking { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_Logging.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * 统一的JVM日志系统 5 | * 6 | *
 7 |  *  实现背景:
 8 |  *            * 曾经很难知道导致JVM性能问题和导致JVM崩溃的根本原因。
 9 |  *            * 不同的JVM日志的碎片化和日志选项,这使得JVM难以进行调试。
10 |  *  解决方法:          
11 |  *            * 对所有的JVM组件引入一个单一的系统,这些JVM组件支持细粒度的和易配置的JVM日志。
12 |  *            
13 |  * @see 
14 |  * @see   
15 |  *     
16 |  * 
17 | * 18 | * @author WGR 19 | * 20 | */ 21 | public class _Logging { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_MultiResolutionImages.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * 多分辨率图像API 5 | * 6 | *
 7 |  *  JEP :
 8 |  *        * 251:Multi-Resolution Images
 9 |  *        * 263:HiDPI Graphics on Windows and Linux
10 |  *        
11 |  *  使用须知:
12 |  *            * 将不同分辨率的图像封装到一张(多分辨率的)图像中,作为它的变体。
13 |  *            * 基于当前屏幕分辨率大小和运用的图像转换算法,从接口MultiResolutionImage获取所需的变体。
14 |  *            * MultiResolutionImage的基础实现是java.awt.image.BaseMultiResolutionImage。
15 |  *            * 新的API定义在java.awt.image包下。
16 |  *            * @see 
17 |  *            * @see 
18 |  * 
19 | * 20 | * @author WGR 21 | * 22 | */ 23 | public class _MultiResolutionImages { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_Multijar.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 多版本兼容jar包 7 | * 8 | *
 9 |  * 
10 |  *  使用说明:多版本兼容jar功能能让你创建仅在特定版本的Java环境中运行库程序选择使用的class版本。
11 |  *  
12 |  * 
13 | * 14 | * @author WGR 15 | * 16 | */ 17 | public class _Multijar { 18 | 19 | /** 20 | * 21 | * 根据不同的jdk,执行不同的class版本 22 | * 当环境为jdk8时,输出:Generated strings: [Java, 8] 23 | * 当环境为jdk9时,输出:Generated strings: [Java, 9] 24 | * 25 | * 说明:由于项目改成maven项目,之前测试用的自定义jar不方便使用,故这里只做演示阐述。 26 | */ 27 | @Test 28 | public void testMultijatr() { 29 | //Application.testMultiJar(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_Nashorn.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * JavaScript引擎Nashorn升级 5 | * 6 | *
 7 |  *  实现背景:
 8 |  *            * Nashorn项目在JDK 9中得到改进,它为Java提供轻量级的Javascript运行时。
 9 |  *            * JDK 9包含一个用来解析Nashorn的ECMAScript语法树的API。
10 |  *            
11 |  * @see 
12 |  * @see       
13 |  * 
14 | * 15 | * @author WGR 16 | * 17 | */ 18 | public class _Nashorn { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_Optional.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Optional; 6 | import java.util.stream.Stream; 7 | 8 | import org.junit.Test; 9 | 10 | /** 11 | * Optional类中提供了转换为Stream的方法:stream() 12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _Optional { 17 | 18 | /** 19 | * 对stream()进行测试 20 | */ 21 | @Test 22 | public void testOptional() { 23 | 24 | List list = new ArrayList<>(); 25 | list.add("Tom"); 26 | list.add("Jerry"); 27 | list.add("Tim"); 28 | 29 | Optional> optional = Optional.ofNullable(list); 30 | 31 | Stream stream = optional.stream().flatMap(x -> x.stream()); 32 | 33 | stream.forEach(System.out::println); // Tom Jerry Tim 34 | 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_SJavac.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * 智能Java编译工具(sjavac) 5 | *
 6 |  *  目的:
 7 |  *        * 智能java编译工具(sjavac)的第一个阶段始于JEP139这个项目,用于在多核处理器情况下提升JDK的编译速度。
 8 |  *        * 改进Java编译工具,并取代目前JDK编译工具javac,继而成为Java环境默认的通用的智能编译工具。
 9 |  * 
10 | * 11 | * @see
12 | * @see 13 | * 14 | * @author WGR 15 | * 16 | */ 17 | public class _SJavac { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_SegCodeCache.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | /** 4 | * 代码分段缓存 5 | * 6 | *
 7 |  *  使用说明:Java 9的另一个性能提升来自于JIT(Just-in-time)编译器。当某段代码被大量重复执行的时候, 
 8 |  *           虚拟机会把这段代码编译成机器码并储存在代码缓存里面, 进而通过访问缓存中不同分段的代码来提升编译器的效率。
 9 |  *
10 |  *  生命周期:
11 |  *            * 永驻代码(JVM 内置 / 非方法代码)
12 |  *            * 短期代码(仅在某些条件下适用的配置性(profiled)代码)
13 |  *            * 长期代码(非配置性代码)
14 |  * 
15 | * 16 | * @see
17 | * 18 | * @author WGR 19 | * 20 | */ 21 | public class _SegCodeCache { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/new11_other/_UnderScore.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java09.new11_other; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * UnderScore(下划线)使用的限制 7 | * 8 | * @author WGR 9 | * 10 | */ 11 | public class _UnderScore { 12 | 13 | /** 14 | * java 9中规定“_”不再可以单独命名标识符了,如果使用,则会报错 15 | */ 16 | @Test 17 | public void testUnderScore(){ 18 | //String _ = "北京"; 19 | //System.out.println(_); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java09/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java9的新特性 3 | * 4 | *
    5 | *
  1. 模块化系统 Jigsaw(Modularity) 6 | *
  2. JShell Java的REPL工具 _Jshell.java 7 | *
  3. 接口的私有方法 _Interface.java 8 | *
  4. 钻石操作符使用升级 _DiamondOperator.java 9 | *
  5. TWR语句的再次改进 _TWR.java 10 | *
  6. 集合的Of方法,快速创建只读集合 _Collection.java 11 | *
  7. 增强的Stream API _Stream.java 12 | *
  8. 全新的Http客户端API _HttpClient.java 13 | *
  9. 轻量级JSON API _JsonAPI.java 14 | *
  10. 钱和货币的API _MoneyAPI.java 15 | *
  11. 其他杂项改进 16 | *
      17 | *
    • 多版本兼容jar包 _Multijar.java 18 | *
    • 下划线的使用限制 _UnderScore.java 19 | *
    • String存储结构变更 _CompactStrings.java 20 | *
    • 多分辨率图像API _MultiResolutionImages.java 21 | *
    • 智能Java编译工具(sjavac) _SJavac.java 22 | *
    • 统一的JVM日志系统 _Logging.java 23 | *
    • javadoc的html5支持(添加搜索框)_JavaDoc.java 24 | *
    • JavaScript引擎Nashorn升级 _Nashorn.java 25 | *
    • java的动态编译器(JIT) _JIT.java 26 | *
    • 代码分段缓存 _SegCodeCache.java 27 | *
    • 改善锁的竞争机制 _Locking.java 28 | *
    • Optional新增方法 _Optional.java 29 | *
    30 | *
31 | * 32 | * @see
What’s New in JDK 9 33 | * 34 | * @author hepengju 35 | * 36 | */ 37 | package com.hepengju.java09; -------------------------------------------------------------------------------- /src/com/hepengju/java10/new01_varinference/_VarInference.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new01_varinference; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | import org.junit.Test; 9 | 10 | 11 | 12 | /** 13 | * JDK10新特性讲解:局部变量类型推断 14 | * JEP 286: Local-Variable Type Inference 15 | * 16 | *
 17 |  *  使用说明:
 18 |  *            * 引入了 var,既保持 Java 对静态类型安全的承诺,又能让开发者省略不必要的局部变量类型的声明。 
 19 |  *  用法示例:
 20 |  *            * 声明的同时赋值
 21 |  *            * 增强的 for循环中的索引
 22 |  *            * 传统 for循环中声明的本地变量
 23 |  *       @See      
 24 |  *  
25 | * 26 | * @author WGR 27 | */ 28 | 29 | class Users{ 30 | private String username; 31 | private Integer userage; 32 | public String getUsername() { 33 | return username; 34 | } 35 | public void setUsername(String username) { 36 | this.username = username; 37 | } 38 | public Integer getUserage() { 39 | return userage; 40 | } 41 | public void setUserage(Integer userage) { 42 | this.userage = userage; 43 | } 44 | @Override 45 | public String toString() { 46 | return "Users [username=" + username + ", userage=" + userage + "]"; 47 | } 48 | 49 | } 50 | 51 | public class _VarInference { 52 | 53 | /** 54 | * 55 | * 该特定注意点: 56 | * 1.只针对局部变量 57 | * 2.var 是保留类型不是关键字。意味着我们还可以用var来定义变量名或者是方法名 58 | * 3.var 不允许赋值null 59 | * 60 | */ 61 | @Test 62 | public void testVarInferencer() { 63 | 64 | 65 | var i = 10; 66 | var str="abc"; 67 | var list = new ArrayList<>(); 68 | list.add("list test var"); 69 | 70 | var set = new HashSet<>(); 71 | set.add("set test var"); 72 | 73 | var map = new HashMap(); 74 | map.put("test", "map test var"); 75 | 76 | var users = new Users(); 77 | users.setUserage(20); 78 | users.setUsername("user test var"); 79 | 80 | System.out.println(i); // 10 81 | System.out.println(str); // abc 82 | 83 | for(var i1=0;i1 keys = map.keySet(); 92 | 93 | for(var key :keys) { 94 | System.out.println(map.get(key)); // map test var 95 | } 96 | 97 | System.out.println(users); // Users [username=user test var, userage=20] 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new02_gcimprove/_GCimprove.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new02_gcimprove; 2 | 3 | 4 | /** 5 | * GC改进和内存管理 6 | * 7 | *
 8 |  *  具体包括 JEP 304 和 JEP 307
 9 |  *      JEP 304 :
10 |  *                 * 将引入一个纯净的垃圾收集器接口,以帮助改进不同垃圾收集器的源代码隔离。 
11 |  *      JEP 307 :
12 |  *                 * 点通过完全GC并行来改善G1最坏情况的等待时间。G1是Java 9中的默认GC,并且此JEP的目标是使G1平行。
13 |  *                 
14 |  *      @See      
15 |  *      @See                        
16 |  * 
17 | * 18 | * @author WGR 19 | */ 20 | public class _GCimprove { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new03_localhandshake/_LocalHandShake.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new03_localhandshake; 2 | 3 | /** 4 | * 线程本地握手 5 | * 6 | *
 7 |  *  JEP 312: Thread-Local Handshakes
 8 |  *  说明:
 9 |  *        * JDK 10将引入一种在线程上执行回调的新方法
10 |  *        * 因此这将会很方便能停止单个线程而不是停止全部线程或者一个都不停。
11 |  *  
12 |  *  @see 
13 |  *  
14 |  * 
15 |  * 
16 |  * @author WGR
17 |  */
18 | public class _LocalHandShake {
19 | 
20 | }
21 | 


--------------------------------------------------------------------------------
/src/com/hepengju/java10/new04_heapallocation/_HeapAllication.java:
--------------------------------------------------------------------------------
 1 | package com.hepengju.java10.new04_heapallocation;
 2 | 
 3 | 
 4 | /**
 5 |  * 在备用存储装置上的堆分配
 6 |  * 
 7 |  * 
 8 |  *     JEP 316: Heap Allocation on Alternative Memory Devices
 9 |  *     JEP 将使得 JVM 能够使用适用于不同类型的存储机制的堆。
10 |  *     @See    
11 |  * 
12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _HeapAllication { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new05_extunicode/_ExtUnicode.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new05_extunicode; 2 | 3 | /** 4 | * 额外的 Unicode 语言标签扩展 5 | * 6 | *
 7 |  *     JEP 314: Additional Unicode Language-Tag Extensions
 8 |  *     改善 java.util.Locale 类和相关的 API 以实现额外 BCP 47 语言标签的 Unicode 扩展。
 9 |  *     @See 
10 |  * 
11 | * 12 | * @author WGR 13 | * 14 | */ 15 | public class _ExtUnicode { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new06_jitcompiler/_JITCompiler.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new06_jitcompiler; 2 | 3 | /** 4 | * 试验性的基于Java的 JIT编译器 5 | * 6 | *
 7 |  *         JEP 317: Experimental Java-Based JIT Compiler
 8 |  *  实现:
 9 |  *        * 将 Graal 编译器研究项目引入到 JDK 中。并给将 Metropolis 项目成为现实,
10 |  *        * 使 JVM 性能与当前 C++ 所写版本匹敌(或有幸超越)提供基础。
11 |  *        
12 |  *    @See 
13 |  *        
14 |  * 
15 | * 16 | * @author WGR 17 | * 18 | */ 19 | public class _JITCompiler { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new07_rootcertificates/_RootCertificates.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new07_rootcertificates; 2 | 3 | 4 | /** 5 | * 开源根证书 6 | * 7 | *
 8 |  *     JEP 319: Root Certificates
 9 |  *  说明:
10 |  *        * 在 JDK 中将提供一套默认的 CA 根证书。关键的安全部件,如 TLS ,在 OpenJDK 构建中将默认有效。
11 |  *        * 这是 Oracle 正在努力确保 OpenJDK 二进制和 Oracle JDK 二进制功能上一样的工作的一部分,是一项有用的补充内容。
12 |  *  
13 |  *  @see 
14 |  *  @See 
15 |  * 
16 | * 17 | * @author WGR 18 | * 19 | */ 20 | public class _RootCertificates { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new08_ca/_new08_ca.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new08_ca; 2 | 3 | /** 4 | * 根证书颁发认证(CA) 5 | * 6 | *
 7 |  * 
 8 |  *  这将使OpenJDK对开发人员更具吸引力,它还旨在减少OpenJDK和Oracle JDK构建之间的差异。
 9 |  *  附:暂时未在网上找到相关资料。
10 |  *  
11 |  * 
12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _new08_ca { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new09_consolidatejdkf/_RemoveJavah.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new09_consolidatejdkf; 2 | 3 | /** 4 | * 5 | * 删除工具javah 6 | * 7 | *
 8 |  *     JEP 313: Remove the Native-Header Generation Tool 
 9 |  *     从JDK中移除了javah工具,这个很简单并且很重要。
10 |  *     @See 
11 |  * 
12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _RemoveJavah { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new10_removejavah/_RemoveJavah.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new10_removejavah; 2 | 3 | /** 4 | * 5 | * 删除工具javah 6 | * 7 | *
 8 |  *     JEP 313: Remove the Native-Header Generation Tool 
 9 |  *     从JDK中移除了javah工具,这个很简单并且很重要。
10 |  *     @See 
11 |  * 
12 | * 13 | * @author WGR 14 | * 15 | */ 16 | public class _RemoveJavah { 17 | 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/new11_other/_API.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java10.new11_other; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.ByteArrayInputStream; 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileNotFoundException; 9 | import java.io.InputStreamReader; 10 | import java.io.PrintWriter; 11 | import java.io.UnsupportedEncodingException; 12 | import java.util.ArrayList; 13 | import java.util.HashMap; 14 | import java.util.HashSet; 15 | import java.util.List; 16 | import java.util.Map; 17 | import java.util.Scanner; 18 | import java.util.Set; 19 | 20 | import org.junit.Test; 21 | 22 | /** 23 | * 24 | * Java10 新增扩展API类库 25 | * 26 | *
 27 |  *  新增方法:
 28 |  *            * copyOf方法
 29 |  *            * 重载toString()方法
 30 |  *            * 流新增构造方法
 31 |  *            * transferTo方法
 32 |  *            * Formatter和Scanner新增构造
 33 |  * 
34 | * 35 | * 36 | * @author WGR 37 | * 38 | */ 39 | public class _API { 40 | 41 | /** 42 | * List/Set/Map 新增加了一个静态方法copyOf() 43 | */ 44 | @Test 45 | public void testCopyOf() { 46 | var list = new ArrayList(); 47 | list.add("a"); 48 | list.add("b"); 49 | list.add("c"); 50 | list.add("d"); 51 | 52 | var list2 = List.copyOf(list); 53 | list2.stream().forEach(System.out::println); // a b c d 54 | 55 | var set = new HashSet(); 56 | set.add("赵"); 57 | set.add("钱"); 58 | set.add("孙"); 59 | set.add("李"); 60 | 61 | var set2 = Set.copyOf(set); 62 | set2.stream().forEach(System.out::println); // 赵 钱 孙 李 63 | 64 | var map = new HashMap<>(); 65 | map.put("k1", "a"); 66 | map.put("k2", "b"); 67 | 68 | var map2 = Map.copyOf(map); 69 | var keys = map2.keySet(); 70 | for (Object object : keys) { 71 | System.out.println(map2.get(object)); // a b 72 | } 73 | } 74 | 75 | /** 76 | * 77 | * 重载toString()方法,通过使用指定的字符集编码字节,将缓冲区的内容转换为字符串。 78 | * @throws UnsupportedEncodingException 79 | * 80 | */ 81 | @Test 82 | public void testToString() throws UnsupportedEncodingException { 83 | 84 | String str = "上海天正"; 85 | ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes("gbk")); 86 | 87 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 88 | 89 | int c = 0; 90 | while((c = bis.read()) != -1) { 91 | bos.write(c); 92 | } 93 | //bos.toString() 默认的使用的UTF-8编码 94 | System.out.println(bos.toString()); 95 | System.out.println(bos.toString("gbk")); 96 | 97 | } 98 | 99 | /** 100 | * java.io.PrintStream、java.io.PrintlWriter新增构造方法 101 | * @throws UnsupportedEncodingException 102 | * @throws FileNotFoundException 103 | */ 104 | @Test 105 | public void testStructure1() throws Exception { 106 | 107 | String str = "上海天正"; 108 | var p = new PrintWriter("d:/aa.txt", "gbk"); 109 | p.println(str); 110 | p.flush(); 111 | p.close(); 112 | 113 | } 114 | 115 | /** 116 | * Reader:transferTo方法 117 | * 注:java9新增的是inputStream的transferTo方法 118 | * 119 | * @throws Exception 120 | * 121 | */ 122 | @Test 123 | public void testTransferTo() throws Exception { 124 | 125 | var reader = new BufferedReader(new InputStreamReader(new FileInputStream("d:/aa.txt"), "gbk")); 126 | var p = new PrintWriter(new File("d:/cc.txt")); 127 | reader.transferTo(p); 128 | p.flush(); 129 | p.close(); 130 | reader.close(); 131 | 132 | } 133 | 134 | /** 135 | * 新增构造方法 136 | * @throws Exception 137 | */ 138 | @Test 139 | public void testStructure2() throws Exception { 140 | 141 | @SuppressWarnings("resource") 142 | var scan = new Scanner(new FileInputStream(new File("d:/aa.txt")),"gbk"); 143 | scan.useDelimiter(" |,"); 144 | while(scan.hasNext()) { 145 | System.out.println(scan.next()); 146 | } 147 | 148 | } 149 | 150 | 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/com/hepengju/java10/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java10的新特性 3 | * 4 | *
    5 | *
  1. 局部变量的类型推断 _VarInference.java 6 | *
  2. GC改进和内存管理 _GCimprove.java 7 | *
  3. 线程本地握手 _LocalHandShake.java 8 | *
  4. 备用内存设置上的堆分配 _HeapAllication.java 9 | *
  5. 其他Unicode语言 - 标记扩展 _ExtUnicode.java 10 | *
  6. 基于Java的实现性JIT编译器 _JITCompiler.java 11 | *
  7. 开源根证书 _RootCertificates.java 12 | *
  8. 根证书颁发认证 13 | *
  9. 将JDK生态整个单个存储库 _ConsolidataJDKF.java 14 | *
  10. 删除工具javah _RemoveJavah.java 15 | *
  11. 其他杂项改进 16 | *
      17 | *
    • copyOf方法 18 | *
    • 重载toString()方法 19 | *
    • 流新增构造方法 20 | *
    • transferTo方法 21 | *
    • Formatter和Scanner新增构造 22 | *
    23 | *
24 | * 25 | * @see
What’s New in JDK 10 26 | * 27 | * @see What’s New in JDK 10 28 | * 29 | * @author hepengju 30 | * 31 | */ 32 | package com.hepengju.java10; -------------------------------------------------------------------------------- /src/com/hepengju/java11/new01_string/_String.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new01_string; 2 | 3 | import java.io.FileInputStream; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * 9 | * 本类对String新增方法探索 10 | * 11 | *
12 |  *  新增阐述:
13 |  *            * 新增strip、stripLeading、stripTrailing方法
14 |  *            * 新增repeat方法,重复
15 |  *            * 新增lines方法,变成流,方便操作
16 |  * 
17 | * @author WGR 18 | * 19 | */ 20 | 21 | public class _String { 22 | 23 | /** 24 | * 新增isBlank方法 25 | * 判断字符串中的字符是否都是空白 26 | */ 27 | @Test 28 | public void testIsBlank() { 29 | 30 | String string = " \t \r\n "; 31 | System.out.println(string.isBlank()); //true 32 | 33 | } 34 | 35 | /** 36 | * 新增strip、stripLeading、stripTrailing方法 37 | * strip 去重字符串首尾的空白, 包括英文和其他所有语言中的空白字符(功能比trim强大) 38 | * stripLeading 去重字符串首部的空白 39 | * stripTrailing 去重字符串尾部的空白 40 | * trim 去重字符串首尾的空白字符, 只能去除码值小于等于32的空白字符 41 | */ 42 | @Test 43 | public void testStrip() { 44 | 45 | String string = " \t \r\n abc \t "; 46 | String string2 = string.strip(); 47 | System.out.println(string2); //abc 48 | System.out.println(string2.length()); //3 49 | 50 | String string3 = string.trim(); 51 | System.out.println(string3); //abc  ;部分特殊空格去掉不了; 52 | System.out.println(string3.length()); //6 53 | 54 | String string4 = string.stripLeading(); 55 | System.out.println(string4); //abc  ;尾部空格没有去掉; 56 | System.out.println(string4.length()); //6 57 | 58 | String string5 = string.stripTrailing(); 59 | System.out.println(string5); // abc; 60 | System.out.println(string5.length()); //10 61 | 62 | } 63 | 64 | /** 65 | * 新增repeat方法,重复 66 | */ 67 | @Test 68 | public void testRepeat() { 69 | String string = "Java"; 70 | String string2 = string.repeat(5); //JavaJavaJavaJavaJava 71 | System.out.println(string2); 72 | } 73 | 74 | /** 75 | * 新增lines方法,变成流,方便操作 76 | * @throws Exception 77 | */ 78 | @Test 79 | public void testLines() throws Exception { 80 | FileInputStream fis = new FileInputStream("src/com/hepengju/java11/new03_string/_String.java"); 81 | byte[] buffer = new byte[fis.available()]; 82 | fis.read(buffer); 83 | fis.close(); 84 | String string = new String(buffer); 85 | string.lines().forEach(System.out::println); //会输出整个文件内容 86 | } 87 | 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new02_varforlambda/_VarForLambda.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new02_varforlambda; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * 对Lambda表达式的Var类型推断 9 | * 10 | *
11 |  * 
12 |  *  JEP 323: Local-Variable Syntax for Lambda Parameters
13 |  *  局部变量类型推断就是左边的类型直接使用 var 定义
14 |  *  而不用写具体的类型,编译器能根据右边的表达式自动推断类型
15 |  *  
16 |  * 
17 | * 18 | * @author WGR 19 | * 20 | */ 21 | public class _VarForLambda { 22 | 23 | /** 24 | * 对Lambda表达式的Var类型推断 25 | */ 26 | @Test 27 | public void testVarForLambda() { 28 | var numbers = new int[]{1, 2, 3, 4, 5, 6, 7}; 29 | 30 | var subset = Arrays.stream(numbers).filter((var a) -> a > 5).toArray(); 31 | for (int i = 0; i < subset.length; i++) { 32 | System.out.println(subset[i]); // 6 7 33 | } 34 | } 35 | 36 | 37 | /** 38 | * var对局部变量的类型推断 39 | */ 40 | @Test 41 | public void testVar() { 42 | 43 | var javastack = "javastack"; 44 | System.out.println(javastack); // javastack 45 | System.out.println(javastack.getClass()); // class java.lang.String 46 | 47 | // var javastack = "javastack"; 等价于 String javastack = "javastack"; 48 | 49 | 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new03_httpClient/_HttpClient.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new03_httpClient; 2 | 3 | import java.net.URI; 4 | import java.net.http.HttpClient; 5 | import java.net.http.HttpRequest; 6 | import java.net.http.HttpResponse; 7 | import java.net.http.HttpResponse.BodyHandler; 8 | import java.net.http.HttpResponse.BodyHandlers; 9 | import java.util.concurrent.CompletableFuture; 10 | 11 | import org.junit.Test; 12 | 13 | /** 14 | * 15 | * JEP 321: HTTP Client (Standard)(重磅) 16 | * 新增HttpClient 17 | * 18 | *
19 |  *  说明:
20 |  *        * Java 9开始引入的一个处理 HTTP请求的的孵化 HTTP Client API,该 API支持同步和异步。
21 |  *        * Java 11 中已经为正式可用状态。
22 |  *        
23 |  *  @See 
24 |  * 
25 | * 26 | * @author WGR 27 | * 28 | */ 29 | public class _HttpClient { 30 | 31 | /** 32 | * 异步方法(sendAsync) 33 | * 优点:不会造成堵塞 34 | * @throws Exception 35 | */ 36 | @Test 37 | public void testName2() throws Exception { 38 | 39 | HttpClient client = HttpClient.newHttpClient(); 40 | HttpRequest request = HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/test/")).build(); 41 | BodyHandler responseBodyHandler = BodyHandlers.ofString(); 42 | 43 | CompletableFuture> sendAsync = client.sendAsync(request, responseBodyHandler); 44 | sendAsync.thenApply(t -> t.body()).thenAccept(System.out::println); 45 | //HttpResponse response = sendAsync.get(); 46 | //String body = response.body(); 47 | //System.out.println(body); 48 | 49 | } 50 | 51 | /** 52 | * 同步方法(send) 53 | * @throws Exception 54 | */ 55 | @Test 56 | public void testSend() throws Exception { 57 | 58 | HttpClient client = HttpClient.newHttpClient(); 59 | HttpRequest request = HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/test/")).build(); 60 | 61 | BodyHandler responseBodyHandler = BodyHandlers.ofString(); 62 | HttpResponse response = client.send(request, responseBodyHandler); 63 | String body = response.body(); 64 | 65 | System.out.println(body);//会输出整个html的内容 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new04_unicode10/_Unicode10.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new04_unicode10; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 7 | * JEP 327: Unicode 10 8 | * Unicode 10.0 增强 9 | * 10 | *
11 |  *  @See 
12 |  *  @See 
13 |  * 
14 | * 15 | * @author WGR 16 | * 17 | */ 18 | public class _Unicode10 { 19 | 20 | /** 21 | * 对Unicode10的测试 22 | */ 23 | @Test 24 | public void testUnicode10() { 25 | String emoj = "\ud83d\ude02\ud83d\ude0d\ud83c\udf89\ud83d\udc4d"; 26 | System.out.println(emoj); // 😂😍🎉👍 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new05_simplify/_Simplify.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new05_simplify; 2 | 3 | /** 4 | * 5 | * 更简化的编译运行程序 6 | * JEP 330: Launch Single-File Source-Code Programs 7 | * 8 | *
 9 |  * 
10 |  *  JEP 330: 增强java启动器支持运行单个java源代码文件的程序。
11 |  *  阐述:
12 |  *        * 执行源文件中的第一个类, 第一个类必须包含主方法。
13 |  *        * 并且不可以使用别源文件中的自定义类, 本文件中的自定义类是可以使用的。
14 |  *  @See 
15 |  *  
16 |  * 
17 | * 18 | * @author WGR 19 | */ 20 | public class _Simplify { 21 | 22 | public void testSimplify() { 23 | 24 | /* OLD 25 | * 编译 javac Javastack.java 26 | * 运行 java Javastack 27 | */ 28 | 29 | /* NOW 30 | * 编译+运行 java Javastack.java 31 | */ 32 | 33 | 34 | 35 | } 36 | 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new06_abandon/_Abandon.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new06_abandon; 2 | 3 | 4 | /** 5 | * 废弃和移除Java类 6 | * 7 | * 8 | *
 9 |  * 
10 |  *  JEP 320: Remove the Java EE and CORBA Modules
11 |  *  在java11中将java9标记废弃的Java EE及CORBA模块移除掉,具体如下:
12 |  * (1) xml相关的,
13 |  *  java.xml.ws, java.xml.bind,java.xml.ws,
14 |  *  java.xml.ws.annotation,jdk.xml.bind,jdk.xml.ws被移除,
15 |  *  只剩下java.xml,java.xml.crypto,jdk.xml.dom这几个模块;
16 |  * (2) EE及CORBA相关的
17 |  *  java.corba,java.se.ee,java.activation,java.transaction被移除,
18 |  *  但是java11新增一个java.transaction.xa模块.
19 |  * 
20 |  *            OTHER
21 |  *  JEP 336: Deprecate the Pack200 Tools and API           
22 |  *  移除项:
23 |  *  1.移除了com.sun.awt.AWTUtilities
24 |  *  2.移除了sun.misc.Unsafe.defineClass
25 |  *    使用 java.lang.invoke.MethodHandles.Lookup.defineClass来替代
26 |  *  3.移除了Thread.destroy()以及 Thread.stop(Throwable)方法
27 |  *  4.移除了sun.nio.ch.disableSystemWideOverlappingFileLockCheck、sun.locale.formatasdefault属性
28 |  *  5.移除了jdk.snmp模块
29 |  *  6.移除了javafx,openjdk估计是从java10版本就移除了,oracle jdk10还尚未移除javafx,
30 |  *    而java11版本则oracle的jdk版本也移除了javaf
31 |  *  7.移除了Java Mission Control,从JDK中移除之后,需要自己单独下载
32 |  *  8.移除了这些Root Certificates :Baltimore Cybertrust Code Signing CA,SECOM ,AOL and Swisscom
33 |  * 
34 |  *  废弃项:
35 |  *  1.废弃了Nashorn JavaScript Engine
36 |  *  2.废弃了-XX+AggressiveOpts选项
37 |  *  3.-XX:+UnlockCommercialFeatures以及-XX:+LogCommercialFeatures选项也不再需要
38 |  *  4.废弃了Pack200工具及其API
39 |  *  
40 |  *  @See 
41 |  *  @See 
42 |  * 
43 |  * 
44 | * 45 | * @author WGR 46 | * 47 | * 48 | */ 49 | public class _Abandon { 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new07_epsilon/Garbage.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new07_epsilon; 2 | 3 | /** 4 | * 垃圾对象 5 | * 6 | * @author hepengju 7 | */ 8 | @SuppressWarnings("unused") 9 | public class Garbage { 10 | 11 | private double d1 = 1; 12 | private double d2 = 2; 13 | 14 | // 这个方法是GC在清除本对象时, 会调用一次 15 | @Override @SuppressWarnings("all") 16 | public void finalize() { 17 | System.out.println(this + " collecting"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new07_epsilon/_Epsilon.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new07_epsilon; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.junit.Test; 7 | 8 | 9 | 10 | /** 11 | * JEP 318: Epsilon: A No-Op Garbage Collector 12 | * Epsilon垃圾收集器 13 | * 14 | *
15 |  *  引入名为Epsilon的垃圾收集器,该收集器不做任何垃圾回收,可用于性能测试、短生命周期的任务等.
16 |  *  
17 |  *  用法如下: 
18 |  *            * -XX:+UseEpsilonGC  (程序很快就因为堆空间不足而退出)
19 |  *  执行结果: 
20 |  *            * Terminating due to java.lang.OutOfMemoryError: Java heap space。
21 |  *  主要用途:
22 |  *            * 性能测试(它可以帮助过滤掉GC引起的性能假象)
23 |  *            * 内存压力测试
24 |  *            * 非常短的JOB任务
25 |  *            * VM接口测试
26 |  * 
27 | * @author WGR 28 | * 29 | */ 30 | 31 | public class _Epsilon { 32 | 33 | /** 34 | * 对Epsilon进行测试 35 | */ 36 | @Test 37 | public void testEpsilon() { 38 | List list = new ArrayList<>(); 39 | boolean flag = true; 40 | int count = 0; 41 | /* 42 | * 没有加-XX:+UseEpsilonGC时,会出现以前内容,最后出现java.lang.OutOfMemoryError. 43 | * 44 | * com.hepengju.java11.new10_epsilon.Garbage@6227d4e5 collecting 45 | * com.hepengju.java11.new10_epsilon.Garbage@50952207 collecting 46 | * com.hepengju.java11.new10_epsilon.Garbage@28375449 collecting 47 | * com.hepengju.java11.new10_epsilon.Garbage@7204167b collecting 48 | */ 49 | while (flag) { 50 | list.add(new Garbage()); 51 | if (count++ == 500) { 52 | list.clear(); 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new08_jfr/_JFR.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new08_jfr; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.hepengju.java11.new07_epsilon.Garbage; 7 | 8 | /** 9 | * JEP 328: Flight Recorder 10 | * 11 | *
12 |  *  具体概述:
13 |  *           * Flight Recorder以前是商业版的特性,在java11当中开源出来
14 |  *           * 它可以导出事件到文件中,之后可以用Java Mission Control来分析
15 |  *  用法如下:
16 |  *           * java -XX:StartFlightRecording
17 |  *           *
18 |  *  @see          
19 |  *  参考命令:
20 |  *           * jfr print test.jfr
21 |  *           * jfr print --events CPULoad,GarbageCollection test.jfr
22 |  *           * jfr print --json --events "GC,JVM,Java" test.jfr
23 |  *           * jfr summary test.jfr
24 |  *           * jfr metadata test.jfr
25 |  *           
26 |  *  测试示例:
27 |  *           * jcmd 3628 JFR.start (3628为java的pid)
28 |  *           * jcmd 3628 JFR.dump filename=test.jfr name =1
29 |  *           * jcmd 3628 JFR.stop (会生成test.jfr的文件)
30 |  *        附:
31 |  *           * 由于Java11没有提供jmc工具(java mission control)
32 |  *           * 只能用Jdk12查看这个test.jfr二进制文件,输入jfr(开启改功能)  
33 |  *           
34 |  * 
35 | * 36 | * @author WGR 37 | * 38 | */ 39 | 40 | public class _JFR { 41 | 42 | /** 43 | * 执行测试方法,测试记录文件 44 | */ 45 | public void testJFR(){ 46 | 47 | List list = new ArrayList<>(); 48 | boolean flag = true; 49 | int count = 0; 50 | while (flag) { 51 | list.add(new Garbage()); 52 | if (count++ == 20) { 53 | list.clear(); 54 | } 55 | try { 56 | Thread.sleep(1); 57 | } catch (InterruptedException e) { 58 | e.printStackTrace(); 59 | } 60 | 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new09_zgc/_ZGC.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new09_zgc; 2 | 3 | 4 | /** 5 | * JEP 333: ZGC: A Scalable Low-Latency Garbage Collector(Experimental)(重磅) 6 | * ZGC垃圾收集器 7 | * 8 | *
 9 |  *    实现:
10 |  *           * 停顿时间不超过10ms
11 |  *           * 停顿时间不随heap大小或存活对象大小增大而增大
12 |  *           * 可以处理从几百兆到几T的内存大小
13 |  *    概述:
14 |  *           * ZGC是个令人兴奋的新垃圾收集器,旨在为大堆提供非常低的暂停时间。
15 |  *           * 它通过使用着色指针和读屏障来实现这一点,这些是Hotspot新近开发的GC技术,并为未来增加了很多可能性。
16 |  *    用法:   
17 |  *           * -XX:+UseZGC
18 |  *    测试:
19 |  *           * 由于ZGC不支持Windows系统,可以在Linux环境自测。
20 |  *           
21 |  *    @See 
22 |  *    @See 
23 |  *    @See 
24 |  *    
25 |  * 
26 | * 27 | * @author WGR 28 | * 29 | */ 30 | public class _ZGC { 31 | 32 | /* 33 | * Error occurred during initialization of VM 34 | * Option -XX:+UseZGC not supported 35 | */ 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new10_lowoverhead/_LowOverhead.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new10_lowoverhead; 2 | 3 | import java.time.Duration; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * JEP 331: Low-Overhead Heap Profiling 10 | * 对低消耗堆分析 11 | * 12 | * @See 13 | * @See 14 | * 15 | * @author WGR 16 | * 17 | */ 18 | public class _LowOverhead { 19 | 20 | /** 21 | * 测试方法 22 | */ 23 | @Test 24 | public void testLowOverhead() { 25 | TimeUnit tu = TimeUnit.DAYS; 26 | // 将 50 小时转换为天数 27 | System.out.println(tu.convert(Duration.ofHours(50))); // 2 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new11_keyagreement/_KeyAgreement.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new11_keyagreement; 2 | 3 | import java.math.BigInteger; 4 | import java.security.KeyFactory; 5 | import java.security.KeyPair; 6 | import java.security.KeyPairGenerator; 7 | import java.security.PublicKey; 8 | import java.security.spec.NamedParameterSpec; 9 | import java.security.spec.XECPublicKeySpec; 10 | 11 | import javax.crypto.KeyAgreement; 12 | 13 | /** 14 | * JEP 324: Key Agreement with Curve25519 and Curve448 15 | * Curve25519 和 Curve448 算法的密钥协议 16 | * 17 | *
18 |  *  目的:
19 |  *        * 密码学要求使用 Curve25519 和Curve448 是因为它们的安全性和性能。
20 |  *        * JDK会增加两个新的接口XECPublicKey 和 XECPrivateKey。
21 |  *        
22 |  *  @See    
23 |  *  @See     
24 |  *   
25 |  * 
26 | * @author WGR 27 | * 28 | */ 29 | public class _KeyAgreement { 30 | 31 | /** 32 | * 示例代码 33 | * @throws Exception 34 | */ 35 | public void testKeyAgreement() throws Exception { 36 | KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH"); 37 | NamedParameterSpec paramSpec = new NamedParameterSpec("X25519"); 38 | kpg.initialize(paramSpec); // equivalent to kpg.initialize(255) 39 | // alternatively: kpg = KeyPairGenerator.getInstance("X25519") 40 | KeyPair kp = kpg.generateKeyPair(); 41 | 42 | KeyFactory kf = KeyFactory.getInstance("XDH"); 43 | BigInteger u = new BigInteger("9999999999999999999999999999999999999999999999999"); 44 | XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u); 45 | PublicKey pubKey = kf.generatePublic(pubSpec); 46 | 47 | KeyAgreement ka = KeyAgreement.getInstance("XDH"); 48 | ka.init(kp.getPrivate()); 49 | ka.doPhase(pubKey, true); 50 | //byte[] secret = ka.generateSecret(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/new12_other/_Other.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java11.new12_other; 2 | 3 | /** 4 | * JEP 181: Nest-Based Access Control(基于嵌套的访问控制) 5 | * JEP 309: Dynamic Class-File Constants(动态类文件常量) 6 | * JEP 315: Improve Aarch64 Intrinsics(改进 Aarch64 函数) 7 | * JEP 332: Transport Layer Security (TLS) 1.3(支持 TLS 1.3) 8 | * 9 | * @See 10 | * @See 11 | * @See 12 | * @See 13 | * 14 | * @author WGR 15 | * 16 | */ 17 | public class _Other { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/hepengju/java11/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java11的新特性 3 | * 4 | *
    5 | *
  1. String新增方法探索 _String.java 6 | *
  2. Lambda表达式的Var类型推断 _VarForLambda.java 7 | *
  3. HttpClient正式可用 _HttpClient.java 8 | *
  4. Unicode 10 _Unicode10.java 9 | *
  5. 更简化的编译运行 _Simplify.java 10 | *
  6. 废弃和移除Java类 _Abandon.java 11 | *
  7. Epsilon垃圾收集器 _Epsilon.java 12 | *
  8. Flight Recorder _JFR.java 13 | *
  9. 对低消耗堆分析 _LowOverhead.java 14 | *
  10. 算法的密钥协议 _KeyAgreement.java 15 | *
  11. 其他杂项改进 16 | *
      17 | *
    • 基于嵌套的访问控制 18 | *
    • 动态类文件常量 19 | *
    • 改进 Aarch64 函数 20 | *
    • 支持 TLS 1.3 21 | *
    22 | *
23 | * 24 | * @see
What's New in JDK 11 25 | * 26 | * @See java11 新特性 27 | * 28 | * WGR:网上视频或者资料大多包含9/10的新特性,11新特性只有部分,还望补充。 29 | * 30 | * @author hepengju 31 | * 32 | */ 33 | package com.hepengju.java11; -------------------------------------------------------------------------------- /src/com/hepengju/java12/new01_switch/_Switch.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java12.new01_switch; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | /** 7 | * switch: 语句和表达式(预览) 8 | * 9 | *
 10 |  *  传统的Switch语句的问题:
 11 |  *      - 匹配是自上而下的, 如果忘记写break, 后面的case语句不论匹配与否都会执行
 12 |  *      - 所有的case语句共用一个块范围, 在不同的case语句定义的变量名不能重复
 13 |  *      - 不能在一个case里写多个执行结果一致的条件
 14 |  *      - 整个switch不能作为表达式返回值
 15 |  *
 16 |  *  Java 12对switch声明语句进行扩展, 可将其作为增强版的 switch 语句或称为 "switch 表达式"来写出更加简化的代码
 17 |  *      - 不仅可以作为语句(statement),还可以作为表达式(expression)
 18 |  *      - 两种写法都可以使用传统的 switch 语法, 或者使用简化的“case L ->”模式匹配语法作用于不同范围并控制执行流
 19 |  *      - 为了保持兼容性, case 条件语句中依然可以使用字符 : ,但不能混用 -> 和 : ,否则会有编译错误
 20 |  *
 21 |  *  预览语言的说明
 22 |  *      Switch 表达式也是作为预览语言功能的第一个语言改动被引入新版 Java 中来的, 预览语言功能的想法是在 2018 年
 23 |  * 初被引入 Java 中的, 本质上讲这是一种引入新特性的测试版的方法. 通过这种方式, 能够根据用户反馈进行升级、更改, 
 24 |  * 在极端情况下, 如果没有被很好的接纳, 则可以完全删除该功能. 预览功能的关键在于它们没有被包含在Java SE规范中
 25 |  *      编译的时候需要追加参数: -parameters --enable-preview
 26 |  * 
27 | * 28 | * @see JEP 325: Switch Expressions 29 | * @author hepengju 30 | */ 31 | public class _Switch { 32 | 33 | /** 34 | * 日枚举 35 | */ 36 | enum DayEnum {MON, TUE, WED, THU, FRI, SAT, SUN;} 37 | private DayEnum day = DayEnum.MON; 38 | 39 | /** 40 | * 旧版switch语句写法 41 | */ 42 | @Test 43 | public void testSwitchOld() { 44 | System.out.print("OldSwitch: "); 45 | switch (day) { 46 | case MON: 47 | case TUE: 48 | case WED: 49 | System.out.println("123"); 50 | break; 51 | case THU: 52 | case FRI: 53 | System.out.println("45"); 54 | break; 55 | case SAT: 56 | System.out.println("party"); 57 | break; 58 | case SUN: 59 | throw new IllegalArgumentException("sun is not allowed"); 60 | } 61 | } 62 | 63 | /** 64 | * 新版switch语句的简化写法 65 | */ 66 | @Test 67 | public void testSwitchNew() { 68 | System.out.print("NewSwitch: "); 69 | // 不存在则什么也不处理, 比如下面不存在SUN 70 | switch (day) { 71 | case MON, TUE, WED -> System.out.println("123"); 72 | case THU, FRI -> System.out.println("45"); 73 | case SAT -> System.out.println("party"); 74 | } 75 | } 76 | 77 | /** 78 | * switch表达式(简单): 表达式必须覆盖所有值或者使用default, 否则编译报错 79 | */ 80 | @Test 81 | public void testSwitchExpressionSimple() { 82 | String str = switch (day) { 83 | case MON, TUE, WED -> "123"; 84 | case THU, FRI -> "45"; 85 | case SAT -> "party"; 86 | default -> "default"; 87 | }; 88 | 89 | Assert.assertEquals("123", str); 90 | } 91 | 92 | /** 93 | * switch表达式(语句块): 可以写一个复杂的语句块, 最后yield返回结果值(jdk12是break关键字) 94 | */ 95 | @Test public void testSwitchExpressionWithYield() { 96 | String str = switch (day) { 97 | case MON, TUE, WED -> "123"; 98 | case THU, FRI -> { 99 | String result = "4" + 5; 100 | yield result; 101 | } 102 | case SAT, SUN -> { 103 | String result = "party"; 104 | yield result; 105 | } 106 | }; 107 | 108 | Assert.assertEquals("123", str); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/com/hepengju/java12/new02_JVMConstantsAPI/_JVMConstantsAPI.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java12.new02_JVMConstantsAPI; 2 | 3 | import org.junit.Test; 4 | 5 | import java.lang.constant.ClassDesc; 6 | 7 | /** 8 | * JVM 常量 API: 9 | * 10 | *
11 |  *      Java 12 中引入 JVM 常量 API,用来更容易地对关键类文件 (key class-file) 和运行时构件(run-time artifacts)的名义描述
12 |  * (nominal description) 进行建模,特别是对那些从常量池加载的常量,这是一项非常技术性的变化,能够以更简单、标准的方式处理可加载常量。
13 |  *      具体来说就是java.base模块新增了java.lang.constant包(而非 java.lang.invoke.constant )。包中定义了一系列基
14 |  * 于值的符号引用(JVMS 5.1)类型,它们能够描述每种可加载常量。
15 |  *
16 |  *      - ConstantDesc: ClassDesc、MethodTypeDesc、MethodHandleDesc
17 |  *      - Constable
18 |  *
19 |  *      String、Integer、Long、Float、Double均实现了这两个接口,而EnumDesc实现了ConstantDesc接口
20 |  * 
21 | * 22 | * @see java.lang.constant 23 | * @see jvms-5 24 | * @see JVM Constants API 25 | * 26 | * @author hepengju 27 | */ 28 | public class _JVMConstantsAPI { 29 | 30 | @Test public void testConstantAPI(){ 31 | // TODO 备注: 不是很理解, 从JEP334看好像是指class文件的解析和生成等情况下使用的 32 | ClassDesc jvmApi = ClassDesc.of("com.hepengju.java12.new02_JVMConstantsAPI", "_JVMConstantsAPI"); 33 | System.out.println(jvmApi); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/hepengju/java12/new03_compactNumber/_CompactNumber.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java12.new03_compactNumber; 2 | 3 | import org.junit.Test; 4 | 5 | import java.text.NumberFormat; 6 | import java.util.Locale; 7 | 8 | /** 9 | * 压缩数字形式显示 10 | * 11 | * @author hepengju 12 | */ 13 | public class _CompactNumber { 14 | 15 | private int num01 = 100; 16 | private int num02 = 10000; 17 | private int num03 = 100_0000; 18 | private int num04 = 1000_0000; 19 | private int num05 = 10_0000_0000; 20 | 21 | @Test 22 | public void testCompactNumber(){ 23 | NumberFormat nf01 = NumberFormat.getCompactNumberInstance(); 24 | NumberFormat nf02 = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT); 25 | NumberFormat nf03 = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.LONG); 26 | NumberFormat nf04 = NumberFormat.getCompactNumberInstance(Locale.US , NumberFormat.Style.SHORT); 27 | NumberFormat nf05 = NumberFormat.getCompactNumberInstance(Locale.US , NumberFormat.Style.LONG); 28 | NumberFormat nf06 = NumberFormat.getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT); 29 | NumberFormat nf07 = NumberFormat.getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.LONG); 30 | 31 | // 默认(根系统区域有关) 32 | out(nf01, num01, num02, num03, num04, num05); // 100 1万 100万 1000万 10亿 33 | 34 | // 中文短, 中文长 35 | out(nf02, num01, num02, num03, num04, num05); // 100 1万 100万 1000万 10亿 36 | out(nf03, num01, num02, num03, num04, num05); // 100 1万 100万 1000万 10亿 37 | 38 | // 英文短, 英文长 39 | out(nf04, num01, num02, num03, num04, num05); // 100 10K 1M 10M 1B 40 | out(nf05, num01, num02, num03, num04, num05); // 100 10 thousand 1 million 10 million 1 billion 41 | 42 | // 日文短, 日文长 43 | out(nf06, num01, num02, num03, num04, num05); // 100 1万 100万 1000万 10億 44 | out(nf07, num01, num02, num03, num04, num05); // 100 1万 100万 1000万 10億 45 | } 46 | 47 | private void out(NumberFormat nf, int... nums){ 48 | for (int num : nums) { 49 | System.out.print(nf.format(num) + "\t"); 50 | } 51 | System.out.println(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/hepengju/java12/new04_other/_Other.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java12.new04_other; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.FileWriter; 7 | import java.io.IOException; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | import java.util.stream.Collectors; 11 | import java.util.stream.Stream; 12 | 13 | import static java.util.stream.Collectors.*; 14 | 15 | /** 16 | * 其他改进 17 | * 18 | *
19 |  *  String新增方法
20 |  *      - transform: 进行映射转换
21 |  *      - indent: 调整String实例的缩进
22 |  *  Files新增mismatch方法
23 |  *  Collectors新增teeing方法: 聚合两个downstream的结果
24 |  * 
25 | */ 26 | public class _Other { 27 | 28 | /** 29 | * 字符串转换(映射) 30 | */ 31 | @Test 32 | public void testStringTransform(){ 33 | var result = "hello".transform(s -> s + " world") 34 | .transform(String::toUpperCase); 35 | Assert.assertEquals("HELLO WORLD", result); 36 | } 37 | 38 | /** 39 | * 字符串缩进 40 | */ 41 | @Test 42 | public void testStringIndent(){ 43 | // 正数增加空格, 负责删除空白字符 44 | var result = " JAVA\n Python\nC=="; 45 | System.out.println(result); 46 | System.out.println(result.indent(4)); 47 | System.out.println(result.indent(-4)); 48 | } 49 | 50 | /** 51 | * 比较文件内容第一个不同字节的位置 52 | */ 53 | @Test 54 | public void testFilesMisMatch() throws IOException { 55 | FileWriter fw01 = new FileWriter("a.txt"); 56 | FileWriter fw02 = new FileWriter("b.txt"); 57 | try(fw01; fw02){ 58 | fw01.write("a"); 59 | fw01.write("b"); 60 | fw01.write("c"); 61 | fw02.write("a"); 62 | fw02.write("1"); 63 | fw02.write("c"); 64 | } 65 | 66 | long mismatch = Files.mismatch(Path.of("a.txt"), Path.of("b.txt")); 67 | System.out.println(mismatch); 68 | 69 | Files.delete(Path.of("a.txt")); 70 | Files.delete(Path.of("b.txt")); 71 | } 72 | 73 | // /** 74 | // * teeing: 三通(管道配件), 形象的表示将两个流汇聚到一个 75 | // */ 76 | // @Test 77 | // public void testCollectorsTeeing(){ 78 | // var result = Stream.of(5, 10, 15, 20).collect( 79 | // teeing(counting(), summingInt(n -> n), NumResult::new) 80 | // ); 81 | // System.out.println(result); // _Other.NumResult(count=4, sum=50) 82 | // } 83 | 84 | // @Data 85 | // @AllArgsConstructor 86 | // class NumResult{ 87 | // private Long count; // 个数 88 | // private Integer sum; // 总数 89 | // } 90 | } 91 | -------------------------------------------------------------------------------- /src/com/hepengju/java12/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java12的新特性 3 | * 4 | *
    5 | *
  1. switch表达式(预览) 6 | *
  2. JVM常量API 7 | *
  3. 压缩数据格式 8 | * 9 | *
  4. Shenandoah GC: 低暂停时间的GC 10 | *
  5. Microbenchmark Suite: 微基准测试套件 11 | *
  6. One AArch64 Port,Not Two: 只保留一个AArch64实现 12 | *
  7. Default CDS Archives: 默认类数据共享归档文件 13 | *
  8. Abortable Mixed Collections for G1: 可中止的G1 Mixed GC 14 | *
  9. Promptly Return Unused Committed Memory from G1: G1及时返回未使用的已分配内存 15 | *
16 | * 17 | * @see What's New in JDK 12 18 | * @see JDK 12 Features 19 | * 20 | * @author hepengju 21 | * 22 | */ 23 | package com.hepengju.java12; -------------------------------------------------------------------------------- /src/com/hepengju/java13/new01_switch/_Switch.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java13.new01_switch; 2 | 3 | /** 4 | * switch: 语句和表达式(预览) 5 | * 6 | *
 7 |  *     在JDK 12中引入了Switch表达式作为预览特性。JDK 13提出了第二个switch表达式预览。JEP 354修改了这个特性,
 8 |  * 它引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield, switch语句(不返回值)应该使用
 9 |  * break。
10 |  *      在 JDK 12中有一个,但是要进行一个更改:要从 switch 表达式中生成一个值 break,要删除with value语句以支持a
11 |  * yield 声明。目的是扩展,switch 以便它可以用作语句或表达式,因此两个表单既可以使用 case ... : 带有连贯符号的
12 |  * 传统标签,也可以使用新 case … -> 标签,而不需要通过,还有一个新的语句用于从 switch 表达式中产生值。这些
13 |  * 更改将简化编码并为模式匹配做好准备。
14 |  *
15 |  *      和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。
16 |  *
17 |  *  参考: java12新特性里面的_Switch, java13仅仅对于switch表达式的返回值由 "break 值" --> "yield 值"
18 |  * 
19 | * 20 | * @author hepengju 21 | */ 22 | public class _Switch { } 23 | -------------------------------------------------------------------------------- /src/com/hepengju/java13/new03_reImplSocket/_ReImplSocket.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java13.new03_reImplSocket; 2 | 3 | /** 4 | * 重新实现旧版套接字API 5 | * 6 | *
 7 |  * 现有问题
 8 |  *  重新实现了古老的 Socket 接口。现在已有的 java.net.Socket 和 java.net.ServerSocket 以及它们的实现类,都可以回溯到 JDK 1.0 时代了。
 9 |  *  - 它们的实现是混合了 Java 和 C 的代码的,维护和调试都很痛苦。
10 |  *  - 实现类还使用了线程栈作为 I/O 的缓冲,导致在某些情况下还需要增加线程栈的大小。
11 |  *  - 支持异步关闭,此操作是通过使用一个本地的数据结构来实现的,这种方式这些年也带来了潜在的不稳定性和
12 |  *  - 跨平台移植问题。该实现还存在几个并发问题,需要彻底解决。
13 |  *  在未来的网络世界,要快速响应,不能阻塞本地方法线程,当前的实现不适合使用了。
14 |  *
15 |  * 新的实现类
16 |  *  全新实现的 NioSocketImpl 来替换JDK1.0的PlainSocketImpl。
17 |  *  - 它便于维护和调试,与 NewI/O (NIO) 使用相同的 JDK 内部结构,因此不需要使用系统本地代码。
18 |  *  - 它与现有的缓冲区缓存机制集成在一起,这样就不需要为 I/O 使用线程栈。
19 |  *  - 它使用 java.util.concurrent 锁,而不是 synchronized 同步方法,增强了并发能力。
20 |  *  - 新的实现是Java 13中的默认实现,但是旧的实现还没有删除,可以通过设置系统属性jdk.net.usePlainSocketImpl来切换到旧版本。
21 |  *
22 |  * @see java.net.SocketImpl
23 |  * 
24 | * 25 | * @author hepengju 26 | */ 27 | public class _ReImplSocket { } 28 | -------------------------------------------------------------------------------- /src/com/hepengju/java13/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java13的新特性 3 | * 4 | *
    5 | *
  1. switch表达式(预览) 6 | *
  2. 文本块(预览) 7 | *
  3. 重新实现旧版套接字API 8 | * 9 | *
  4. 动态CDS档案(动态类数据共享归档) 10 | *
  5. ZGC:取消使用未使用的内存 11 | *
12 | * 13 | * @see JDK 13 Features 14 | * 15 | * @author hepengju 16 | * 17 | */ 18 | package com.hepengju.java13; -------------------------------------------------------------------------------- /src/com/hepengju/java14/new01_instanceof/_Instanceof.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java14.new01_instanceof; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * instanceof模式匹配(预览) 7 | * 8 | *
 9 |  *     说明: 通过对 instanceof 运算符进行模式匹配来增强Java编程语言
10 |  *     优点: 更简洁, 更安全
11 |  * 
12 | */ 13 | public class _Instanceof { 14 | 15 | private Object obj = "Java"; 16 | 17 | /** 18 | * 旧版写法 19 | */ 20 | @Test 21 | public void testOld() { 22 | if (obj instanceof String) { 23 | String str = (String) obj; 24 | System.out.println("旧版写法结果: " + str.toUpperCase()); 25 | } else { 26 | System.out.println("not string: " + obj.hashCode()); 27 | } 28 | } 29 | 30 | @Test 31 | public void testNew() { 32 | if (obj instanceof String str) { 33 | System.out.println("新版写法结果: " + str.toUpperCase()); 34 | } else { 35 | System.out.println("not string: " + obj.hashCode()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/hepengju/java14/new02_jpackage/_JPackage.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java14.new02_jpackage; 2 | 3 | /** 4 | * jpackage 打包工具 5 | * 6 | * @see 打包工具 7 | */ 8 | public class _JPackage { 9 | } 10 | -------------------------------------------------------------------------------- /src/com/hepengju/java14/new03_JFREventStreaming/_JFREventStreaming.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java14.new03_JFREventStreaming; 2 | 3 | public class _JFREventStreaming { 4 | } 5 | -------------------------------------------------------------------------------- /src/com/hepengju/java14/new04_helpfulNPE/_HelpfulNPE.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java14.new04_helpfulNPE; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import org.junit.Test; 6 | 7 | /** 8 | * 改善的NPE异常提示 9 | */ 10 | public class _HelpfulNPE { 11 | 12 | @Test 13 | public void testNPE(){ 14 | Pet pet = new Pet("silly dog"); 15 | User user = new User("hepengju", pet); 16 | 17 | // java.lang.NullPointerException 18 | System.out.println(user.getPet().getName()); 19 | 20 | // java.lang.NullPointerException: Cannot invoke "com.hepengju.java14.new04_helpfulNPE.Pet.getName()" 21 | // because the return value of "com.hepengju.java14.new04_helpfulNPE.User.getPet()" is null 22 | //user.setPet(null); 23 | //System.out.println(user.getPet().getName()); 24 | 25 | // java.lang.NullPointerException: Cannot invoke "com.hepengju.java14.new04_helpfulNPE.User.getPet()" 26 | // because "user" is null 27 | user = null; 28 | System.out.println(user.getPet().getName()); 29 | } 30 | } 31 | 32 | @Data @AllArgsConstructor 33 | class User { 34 | private String name; 35 | private Pet pet; 36 | } 37 | 38 | @Data @AllArgsConstructor 39 | class Pet { 40 | String name; 41 | } 42 | -------------------------------------------------------------------------------- /src/com/hepengju/java14/new05_record/_Record.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java14.new05_record; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 记录类 7 | */ 8 | public class _Record { 9 | 10 | @Test 11 | public void testRecord() { 12 | Point p1 = new Point(10, 10); 13 | Point p2 = new Point(10, 10); 14 | 15 | System.out.println(p1); // Point[x=10, y=10] 16 | System.out.println(p1 == p2); // false 17 | System.out.println(p1.equals(p2)); // true 18 | } 19 | } 20 | 21 | 22 | record Point(int x, int y) {} 23 | 24 | -------------------------------------------------------------------------------- /src/com/hepengju/java14/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java13的新特性 3 | * 4 | *
 5 |  *     1. instanceof模式匹配(预览)
 6 |  *     2. 打包工具(孵化器)
 7 |  *     3. JFR事件流
 8 |  *     4. 优化的NPE提示
 9 |  *     5. 记录类型 record(预览)
10 |  * 
11 | * 12 | * @see JDK 14 Features 13 | * @see JDK 14如期发布,16个新特性快速预览 14 | * @see JDK 14: Java 14 中的新特性 15 | * @see Java14来了 16 | * 17 | * @author hepengju 18 | */ 19 | package com.hepengju.java14; -------------------------------------------------------------------------------- /src/com/hepengju/java15/new01_sealedclass/_SealedClass.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java15.new01_sealedclass; 2 | 3 | 4 | /** 5 | * 密封的类和接口(预览) 6 | * 7 | *
 8 |  *  概述: 通过密封的类和接口来增强 Java 编程语言,这是新的预览特性。
 9 |  *
10 |  *  目的: 用于限制超类的使用,密封的类和接口限制其它可能继承或实现它们的其它类或接口。
11 |  *
12 |  *      这个特性的目标包括——允许类或接口的开发者来控制哪些代码负责实现,提供了比限制使用超类的访问修饰符声明方式更多选择,
13 |  * 并通过支持对模式的详尽分析而支持模式匹配的未来发展。
14 |  *      在Java中,类层次结构通过继承实现代码的重用,父类的方法可以被许多子类继承。
15 |  * 但是,类层次结构的目的并不总是重用代码。有时,其目的是对域中存在的各种可能性进行建模,
16 |  * 例如图形库支持的形状类型或金融应用程序支持的贷款类型。当以这种方式使用类层次结构时,我们可能需要限制子类集从而来简化建模。
17 |  *
18 |  *  使用:
19 |  *      使用修饰符sealed,您可以将一个类声明为密封类。密封的类使用reserved关键字permits列出可以直接扩展它的类。
20 |  *      1. 密封类必须有子类
21 |  *      2. 子类应为 sealed、non-sealed 或 final 修饰符
22 |  * 
23 | * 24 | * @see JEP 360: Sealed Classes (Preview) 25 | */ 26 | public class _SealedClass {} 27 | 28 | // 示例1: 图形, 只允许 圆形,矩形,正方形 29 | // 注意: 也可以不使用 permits 关键字,然后将类定义与类放在相同的文件中, 即如下: 30 | //sealed class Shape /*permits Circle, Rectangle, Square, ExtShape*/ {}; 31 | sealed class Shape permits Circle, Rectangle, Square, ExtShape {}; 32 | final class Circle extends Shape {} 33 | final class Rectangle extends Shape {} 34 | final class Square extends Shape {} 35 | 36 | // 以下仅仅为展示语法, 无实际意义 37 | sealed class ExtShape extends Shape permits ExtShape01, ExtShape02, ExtShapeXX {} 38 | final class ExtShape01 extends ExtShape {} 39 | final class ExtShape02 extends ExtShape {} 40 | non-sealed class ExtShapeXX extends ExtShape {} 41 | 42 | // 示例2: 和record关键字一起使用 43 | sealed interface Expr permits ConstantExpr, PlusExpr, TimesExpr, NegExpr {} 44 | record ConstantExpr(int i) implements Expr {} 45 | record PlusExpr(Expr a, Expr b) implements Expr {} 46 | record TimesExpr(Expr a, Expr b) implements Expr {} 47 | record NegExpr(Expr e) implements Expr {} -------------------------------------------------------------------------------- /src/com/hepengju/java15/new02_hiddenclass/_HiddenClass.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java15.new02_hiddenclass; 2 | 3 | /** 4 | * 隐藏类: TODO 没太看懂, 也就不知道如何编写示例 5 | * 6 | *
 7 |  *      该提案通过启用标准 API 来定义无法发现且具有有限生命周期的隐藏类,从而提高 JVM 上所有语言的效率。
 8 |  * JDK内部和外部的框架将能够动态生成类,而这些类可以定义隐藏类。通常来说基于JVM的很多语言都有动态生成类的机制,
 9 |  * 这样可以提高语言的灵活性和效率。
10 |  *      - 隐藏类天生为框架设计的,在运行时生成内部的class。
11 |  *      - 隐藏类只能通过反射访问,不能直接被其他类的字节码访问。
12 |  *      - 隐藏类可以独立于其他类加载、卸载,这可以减少框架的内存占用。
13 |  *
14 |  *      Hidden Classes是什么呢?
15 |  *      Hidden Classes就是不能直接被其他class的二进制代码使用的class。Hidden Classes主要被一些框架用来生成运行时类,
16 |  * 但是这些类不是被用来直接使用的,而是通过反射机制来调用。比如在JDK8中引入的lambda表达式,JVM并不会在编译的时候将lambda
17 |  * 表达式转换成为专门的类,而是在运行时将相应的字节码动态生成相应的类对象。另外使用动态代理也可以为某些类生成新的动态类。
18 |  *
19 |  *      那么我们希望这些动态生成的类需要具有什么特性呢?
20 |  *      - 不可发现性。因为我们是为某些静态的类动态生成的动态类,所以我们希望把这个动态生成的类看做是静态类的一部分。所以我们不希望除了该静态类之外的其他机制发现。
21 |  *      - 访问控制。我们希望在访问控制静态类的同时,也能控制到动态生成的类。
22 |  *      - 生命周期。动态生成类的生命周期一般都比较短,我们并不需要将其保存和静态类的生命周期一致。
23 |  *
24 |  *      API的支持
25 |  *      所以我们需要一些API来定义无法发现的且具有有限生命周期的隐藏类。这将提高所有基于JVM的语言实现的效率。
26 |  *      比如:
27 |  *          java.lang.reflect.Proxy可以定义隐藏类作为实现代理接口的代理类。
28 |  *          java.lang.invoke.StringConcatFactory可以生成隐藏类来保存常量连接方法;
29 |  *          java.lang.invoke.LambdaMetaFactory可以生成隐藏的nestmate类,以容纳访问封闭变量的lambda主体;
30 |  *
31 |  *      普通类是通过调用ClassLoader::defineClass创建的,而隐藏类是通过调用Lookup::defineHiddenClass创建的。
32 |  * 这使JVM从提供的字节中派生一个隐藏类,链接该隐藏类,并返回提供对隐藏类的反射访问的查找对象。调用程序可以通过返回的
33 |  * 查找对象来获取隐藏类的Class对象。
34 |  * 
35 | * 36 | * @see JEP 371: Hidden Classes 37 | */ 38 | public class _HiddenClass { 39 | } -------------------------------------------------------------------------------- /src/com/hepengju/java15/new03_textblock/_TextBlock.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java15.new03_textblock; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 文本块(正式发布) 7 | * 8 | * @see com.hepengju.java13.new02_textblock._TextBlock 9 | */ 10 | public class _TextBlock { 11 | 12 | /** 13 | * 新增默认的\, 输出为单行结果 14 | */ 15 | @Test public void testToOneLine() { 16 | String sql = 17 | """ 18 | SELECT employee_id,last_name,salary,department_id \ 19 | FROM employees \ 20 | WHERE department_id in (40,50,60) \ 21 | ORDER BY department_id ASC\ 22 | """; 23 | System.out.println("###"); 24 | // SELECT employee_id,last_name,salary,department_id FROM employees WHERE department_id in (40,50,60) ORDER BY department_id ASC 25 | System.out.println(sql); 26 | System.out.println("###"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/com/hepengju/java15/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java15的新特性 3 | * 4 | *
 5 |  *     1. 密封类(预览)
 6 |  *     2. 隐藏类
 7 |  *     3. 文本块正式
 8 |  *     4. ZGC正式
 9 |  *     5. 记录类型 record(预览)
10 |  * 
11 | * 12 | * @see JDK 15 Features 13 | * @see 尚硅谷_Java15新特性教程 14 | * 15 | * @author hepengju 16 | */ 17 | package com.hepengju.java15; -------------------------------------------------------------------------------- /src/com/hepengju/java16/new01_toList/_StreamToList.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java16.new01_toList; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.List; 6 | import java.util.function.Consumer; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | /** 11 | * Stream流新增 toList 方法 12 | * 13 | * @see com.hepengju.java08.new04_streamAPI._StreamAPI 14 | */ 15 | public class _StreamToList { 16 | 17 | @Test 18 | public void testToList() { 19 | var srcList = List.of("a", "b", "c"); // Java9新增的of方法 20 | var list01 = srcList.stream().collect(Collectors.toList()); // Java8的搜集方法 21 | var list02 = srcList.stream().toList(); // Java16 简化的搜集方法, 注意: 结果是不可变的List 22 | 23 | System.out.println(list01); 24 | System.out.println(list02); 25 | 26 | list01.add("d"); // OK 27 | //list02.add("d"); // java.lang.UnsupportedOperationException 28 | } 29 | 30 | @Test 31 | public void testMapMulti01() { 32 | List numbers = List.of(1, 2.0, 3.3, 9999999999L, 0); 33 | List integers = numbers.stream().mapMulti((number, consumer) -> { 34 | if (number instanceof Integer i) consumer.accept(i); 35 | }).collect(Collectors.toList()); 36 | System.out.println(integers); // [1, 0] 37 | } 38 | 39 | @Test 40 | public void testMapMulti02(){ 41 | var nestedList = List.of(1, List.of(2, List.of(3, 4)), 5); 42 | List list = nestedList.stream().mapMulti(C::expandIterable).toList(); 43 | System.out.println(list); // [1, 2, 3, 4, 5] 44 | } 45 | } 46 | 47 | class C { 48 | static void expandIterable(Object e, Consumer c) { 49 | if (e instanceof Iterable elements) { 50 | for (Object ie : elements) { 51 | expandIterable(ie, c); 52 | } 53 | } else if (e != null) { 54 | c.accept(e); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/com/hepengju/java17/new01_randomgenerator/_RandomGenerator.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java17.new01_randomgenerator; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.random.RandomGenerator; 7 | 8 | /** 9 | * 增强的伪随机数生成器 RandomGenerator,适应基于stream操作的程序 10 | */ 11 | public class _RandomGenerator { 12 | 13 | @Test 14 | public void testRandomGenerator() { 15 | // L32X64MixRandom 16 | var random = RandomGenerator.getDefault(); 17 | 18 | System.out.println(random.nextInt(10)); 19 | System.out.println(random.nextDouble(10)); 20 | System.out.println(random.nextGaussian()); 21 | System.out.println(Arrays.toString(random.ints(5).toArray())); // stream流 22 | 23 | // L64X128MixRandom 24 | RandomGenerator random2 = RandomGenerator.of("L64X128MixRandom"); 25 | System.out.println(Arrays.toString(random2.ints(5).toArray())); 26 | } 27 | } -------------------------------------------------------------------------------- /src/com/hepengju/java17/new03_sealedclass/_SealedClass.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java17.new03_sealedclass; 2 | 3 | 4 | /** 5 | * 密封类和接口(正式) 6 | * 7 | * @see com.hepengju.java15.new01_sealedclass._SealedClass 8 | */ 9 | public class _SealedClass {} 10 | -------------------------------------------------------------------------------- /src/com/hepengju/java17/new04_hexformat/_HexFormat.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java17.new04_hexformat; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | import java.util.HexFormat; 7 | 8 | /** 9 | * 十六进制格式化工具类 10 | * 11 | * @see HexFormat 12 | */ 13 | public class _HexFormat { 14 | 15 | @Test 16 | public void testToFromHexDigits() { 17 | HexFormat hex = HexFormat.of(); 18 | byte b = 127; 19 | String byteStr = hex.toHexDigits(b); // toHexDigits 20 | byte byteVal = (byte) hex.fromHexDigits(byteStr); // fromHexDigits 21 | assert (byteStr.equals("7f")); 22 | assert (b == byteVal); 23 | } 24 | 25 | @Test 26 | public void testFormatParseHex() { 27 | HexFormat commaFormat = HexFormat.ofDelimiter(", ").withPrefix("#"); 28 | byte[] bytes = {0, 1, 2, 3, 124, 125, 126, 127}; 29 | // #00, #01, #02, #03, #7c, #7d, #7e, #7f <== HexFormat.ofDelimiter(", ").withPrefix("#") 30 | // 00:01:02:03:7C:7D:7E:7F <== HexFormat.ofDelimiter(":").withUpperCase() 31 | String str = commaFormat.formatHex(bytes); // formatHex 32 | byte[] parsed = commaFormat.parseHex(str); // parseHex 33 | assert (Arrays.equals(bytes, parsed)); 34 | System.out.println(str); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/hepengju/java17/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java17的新特性 3 | * 4 | *
 5 |  *      306: Restore Always-Strict Floating-Point Semantics   恢复始终执行严格模式的浮点定义
 6 |  *      356: Enhanced Pseudo-Random Number Generators         增强型伪随机数生成器           
 7 |  *      382: New macOS Rendering Pipeline                     新的 macOS 渲染管道
 8 |  *      391: macOS/AArch64 Port                               macOS AArch64 端口
 9 |  *      398: Deprecate the Applet API for Removal             弃用 Applet API
10 |  *      403: Strongly Encapsulate JDK Internals               JDK 内部强封装
11 |  *      406: Pattern Matching for switch (Preview)            为 switch 支持模式匹配(预览)
12 |  *      407: Remove RMI Activation                            移除 RMI 激活
13 |  *      409: Sealed Classes                                   密封类
14 |  *      410: Remove the Experimental AOT and JIT Compiler     移除实验性的 AOT 和 JIT 编译器
15 |  *      411: Deprecate the Security Manager for Removal       弃用安全管理器
16 |  *      412: Foreign Function & Memory API (Incubator)        外部函数和内存 API(孵化中)
17 |  *      414: Vector API (Second Incubator)                    矢量 API(二次孵化中)
18 |  *      415: Context-Specific Deserialization Filters         上下文特定反序列化过滤器
19 |  * 
20 | * 21 | * @see OpenJDK17 22 | * @see OracleJDK17 23 | * 24 | * @author hepengju 25 | */ 26 | package com.hepengju.java17; -------------------------------------------------------------------------------- /src/com/hepengju/java18/new01_utf8/_UTF8.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java18.new01_utf8; 2 | 3 | import org.junit.Test; 4 | 5 | import java.nio.charset.Charset; 6 | 7 | /** 8 | * 指定 UTF-8 作为标准 Java API 的默认字符集 9 | * 10 | *
11 |  * 在 JDK 17 及更早版本中,默认字符集是在 Java 虚拟机运行时才确定的,取决于不同的操作系统、区域设置等因素,因此存在潜在的风险。
12 |  * 从这个版本开始,依赖于默认字符集的 API 会在所有实现、操作系统、语言环境和配置中保持一致。
13 |  *
14 |  * 可以使用以下命令查看当前 JDK 的默认字符集:
15 |  *      java -XshowSettings:properties -version | grep file.encoding
16 |  *
17 |  *      $JDK18_HOME/bin/java -XshowSettings:properties -version | grep file.encoding
18 |  *          file.encoding = UTF-8
19 |  *      $JDK17_HOME/bin/java -XshowSettings:properties -version | grep file.encoding
20 |  *          file.encoding = GBK  (Windows简体中文版)
21 |  * 
22 | */ 23 | public class _UTF8 { 24 | 25 | @Test 26 | public void testUTF8() { 27 | System.out.println(System.getProperty("native.encoding")); // GBK 28 | System.out.println(System.getProperty("file.encoding")); // UTF-8 29 | System.out.println(Charset.defaultCharset()); // UTF-8 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/hepengju/java18/new02_webserver/_SimpleWebServer.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java18.new02_webserver; 2 | 3 | /** 4 | * 简单 Web 服务器 5 | * 6 | *
 7 |  *  jwebserver 默认8000端口,当前目录作为根目录
 8 |  *  jwebserver -h 查看帮助选项
 9 |  *
10 |  *  Usage: jwebserver [-b bind address] [-p port] [-d directory]
11 |  *                    [-o none|info|verbose] [-h to show options]
12 |  *                    [-version to show version information]
13 |  *  Options:
14 |  *  -b, --bind-address    - Address to bind to. Default: 127.0.0.1 (loopback).
15 |  *                          For all interfaces use "-b 0.0.0.0" or "-b ::".
16 |  *  -d, --directory       - Directory to serve. Default: current directory.
17 |  *  -o, --output          - Output format. none|info|verbose. Default: info.
18 |  *  -p, --port            - Port to listen on. Default: 8000.
19 |  *  -h, -?, --help        - Prints this help message and exits.
20 |  *  -version, --version   - Prints version information and exits.
21 |  *  To stop the server, press Ctrl + C.
22 |  *
23 |  * 
24 | */ 25 | public class _SimpleWebServer { 26 | } 27 | -------------------------------------------------------------------------------- /src/com/hepengju/java18/new03_snippet/ShowOptional.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java18.new03_snippet; 2 | 3 | import java.util.Optional; 4 | 5 | public class ShowOptional { 6 | void show(Optional v) { 7 | // @start region="example" 8 | if (v.isPresent()) { 9 | System.out.println("v: " + v.get()); 10 | } 11 | // @end 12 | } 13 | } -------------------------------------------------------------------------------- /src/com/hepengju/java18/new03_snippet/_Snippet.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java18.new03_snippet; 2 | 3 | import java.util.stream.Stream; 4 | 5 | /** 6 | * 代码片段 7 | *

8 | * 示例1 9 | * A simple program. 10 | * {@snippet : 11 | * class HelloWorld { 12 | * public static void main(String... args) { 13 | * System.out.println("Hello World!"); // @highlight substring="println" 14 | * System.out.println("Hello World!"); // @replace regex='".*"' replacement="..." 15 | * System.out.println("Hello World!"); // @link substring="System.out" target="System#out" 16 | * } 17 | * } 18 | *} 19 | *

20 | * 示例2 21 | * The following code shows how to use {@code Optional.isPresent}: 22 | * {@snippet file = "ShowOptional.java" region = "example"} 23 | * 24 | *

25 | * 示例3 26 | * Here are the configuration properties: 27 | * {@snippet file = "config.properties"} 28 | * 29 | * @see Stream 旧版的@code写法参考,其实现比较简单 30 | * @see JEP413 31 | * @see A Programmmer's Guide to Snippets 32 | */ 33 | public class _Snippet { 34 | } 35 | -------------------------------------------------------------------------------- /src/com/hepengju/java18/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java18的新特性 3 | * 4 | *

 5 |  *      400: UTF-8 by Default                                 默认UTF8字符集
 6 |  *      408: Simple Web Server                                简单Web服务器
 7 |  *      413: Code Snippets in Java API Documentation          简化文档代码片段
 8 |  *      416: Reimplement Core Reflection with Method Handles  重新实现反射核心机制(Method Handles)
 9 |  *      417: Vector API (Third Incubator)                     矢量API(三次孵化中)
10 |  *      418: Internet-Address Resolution SPI                  互联网地址解析SPI
11 |  *      419: Foreign Function & Memory API (Second Incubator) 外部函数和内存 API(第二孵化器)
12 |  *      420: Pattern Matching for switch (Second Preview)     switch 模式匹配(二次预览)
13 |  *      421: Deprecate Finalization for Removal               弃用Finalization
14 |  * 
15 | * 16 | * @see OpenJDK18 17 | * @see OracleJDK18 18 | * 19 | * @see 走进JDK18新特性 20 | * 21 | * @author hepengju 22 | */ 23 | package com.hepengju.java18; -------------------------------------------------------------------------------- /src/com/hepengju/java19/new01_newmapset/_NewMapSet.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java19.new01_newmapset; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * 新的创建Map和Set的静态方法(指定元素个数) 9 | */ 10 | public class _NewMapSet { 11 | 12 | /** 13 | * The int-argument constructors for these classes set the "capacity" (internal table size) 14 | * which is not the same as the number of elements that can be accommodated. 15 | * The capacity is related to the number of elements by a simple but error-prone calculation. 16 | * For this reason, programs should use these new static factory methods in preference to the int-argument constructors. 17 | */ 18 | @Test 19 | @SuppressWarnings("unused") 20 | public void testHashMap(){ 21 | // 构造函数传入的整数是设置”容量“(内部表大小) 22 | var oldMap = new HashMap(1); 23 | 24 | // 容量与元素个数的关系:容量=Math.ceil(个数 / 负载因子) ,默认负载因子为0.75 25 | // 静态方法传入的整数是元素的个数 ==> 更推荐 26 | var newMap = HashMap.newHashMap(1); 27 | } 28 | 29 | @Test 30 | public void testOther(){ 31 | LinkedHashMap.newHashMap(10); 32 | WeakHashMap.newWeakHashMap(10); 33 | HashSet.newHashSet(10); 34 | LinkedHashSet.newLinkedHashSet(10); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/hepengju/java19/new02_minguodate/_MinguoDate.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java19.new02_minguodate; 2 | 3 | import org.junit.Test; 4 | 5 | import java.time.chrono.*; 6 | import java.time.temporal.IsoFields; 7 | 8 | import static java.lang.System.out; 9 | 10 | /** 11 | * Support for IsoFields in JapaneseDate/MinguoDate/ThaiBuddhistDate (JDK-8279185) 12 | * 13 | *
14 |  *  IsoChronology             公历
15 |  *  MinguoChronology          民国历
16 |  *  JapaneseChronology        日本历
17 |  *  ThaiBuddhistChronology    泰国历
18 |  *  HijrahChronology          伊斯兰历法、回历
19 |  *  
20 | */ 21 | public class _MinguoDate { 22 | 23 | @Test 24 | public void testMinguoDate() { 25 | out.println(IsoChronology.INSTANCE.dateNow()); // 2022-09-29 26 | out.println(MinguoChronology.INSTANCE.dateNow()); // Minguo ROC 111-09-29 27 | out.println(JapaneseChronology.INSTANCE.dateNow()); // Japanese Reiwa(令和) 4-09-29 28 | out.println(HijrahChronology.INSTANCE.dateNow()); // Hijrah-umalqura AH 1444-03-03 29 | out.println(ThaiBuddhistChronology.INSTANCE.dateNow()); // ThaiBuddhist BE 2565-09-29 30 | 31 | // 输出第几个季度(此处为新特性) 32 | out.println(JapaneseDate.now().getLong(IsoFields.QUARTER_OF_YEAR)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/hepengju/java19/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java19的新特性 3 | * 4 | *
 5 |  *      405: Record Patterns (Preview)                       记录模式(预览)
 6 |  *      422: Linux/RISC-V Port                               将JDK移植到Linux/RISC-V平台 (RISC是指精简指令集)
 7 |  *      424: Foreign Function & Memory API (Preview)         外部函数和内存 API(预览)
 8 |  *      425: Virtual Threads (Preview)                       虚拟线程(预览)
 9 |  *      426: Vector API (Fourth Incubator)                   矢量API(四次孵化中)
10 |  *      427: Pattern Matching for switch (Third Preview)     switch 模式匹配(三次预览)
11 |  *      428: Structured Concurrency (Incubator)              结构化并发(孵化中)
12 |  * 
13 | * 14 | * @see OpenJDK19 15 | * @see OracleJDK19 16 | * 17 | * @author hepengju 18 | */ 19 | package com.hepengju.java19; 20 | -------------------------------------------------------------------------------- /src/com/hepengju/java20/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java20的新特性 3 | * 4 | *
 5 |  *      429: Scoped Values (Incubator)                          范围值(孵化)
 6 |  *      432: Record Patterns (Second Preview)                   记录模式(第二次预览)
 7 |  *      433: Pattern Matching for switch (Fourth Preview)       switch模式匹配(第四次预览)
 8 |  *      434: Foreign Function & Memory API (Second Preview)     外部函数和内存API(第二次预览)
 9 |  *      436: Virtual Threads (Second Preview)                   虚拟线程(第二次预览)
10 |  *      437: Structured Concurrency (Second Incubator)          结构化并发(第二次孵化)
11 |  *      438: Vector API (Fifth Incubator)                       矢量API(第五次孵化)
12 |  * 
13 | * 14 | * @see OpenJDK20 15 | * @see OracleJDK20 16 | * 17 | * @author hepengju 18 | */ 19 | package com.hepengju.java20; -------------------------------------------------------------------------------- /src/com/hepengju/java21/new01_sequenced_collections/_SequencedCollections.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java21.new01_sequenced_collections; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * 有序集合 9 | */ 10 | public class _SequencedCollections { 11 | 12 | /** 13 | * @see java.util.SequencedCollection 14 | */ 15 | @Test 16 | public void testSequencedCollection() { 17 | List list = new ArrayList<>(); 18 | list.add("a"); 19 | list.add("b"); 20 | list.add("c"); 21 | System.out.println(list); // [a, b, c] 22 | 23 | // 获取 24 | System.out.println(list.get(0) + ":" + list.get(list.size() - 1)); // a:c 25 | System.out.println(list.getFirst() + ":" + list.getLast()); // a:c 26 | 27 | // 添加 28 | list.addFirst("newFirst"); 29 | list.addLast("newLast"); 30 | System.out.println(list); // [newFirst, a, b, c, newLast] 31 | 32 | // 删除 33 | list.removeFirst(); 34 | list.removeLast(); 35 | System.out.println(list); // [a, b, c] 36 | 37 | // 翻转 38 | List reversed = list.reversed(); 39 | System.out.println(reversed); // [c, b, a] 40 | } 41 | 42 | /** 43 | * @see java.util.SequencedSet 44 | */ 45 | @Test 46 | public void testSequencedSet() { 47 | SequencedSet set = new LinkedHashSet(); 48 | set.add("a"); 49 | set.add("b"); 50 | set.add("c"); 51 | 52 | System.out.println(set); // [a, b, c] 53 | 54 | // 获取 55 | System.out.println(set.getFirst()); // a 56 | System.out.println(set.getLast()); // c 57 | 58 | // 添加 59 | set.addFirst("newFirst"); 60 | set.addLast("newLast"); 61 | System.out.println(set); // [newFirst, a, b, c, newLast] 62 | 63 | // 删除 64 | set.removeFirst(); 65 | set.removeLast(); 66 | System.out.println(set); // [a, b, c] 67 | 68 | // 翻转 69 | SequencedSet reversed = set.reversed(); 70 | System.out.println(reversed); // [c, b, a] 71 | } 72 | 73 | /** 74 | * @see java.util.SequencedMap 75 | */ 76 | @Test 77 | public void testSequencedMap() { 78 | SequencedMap map = new LinkedHashMap<>(); 79 | map.put("src", 9); 80 | 81 | // put首尾 82 | map.putFirst("a", 1); 83 | map.putLast("c", 3); 84 | System.out.println(map); // {a=1, src=9, c=3} 85 | 86 | // entry首尾 87 | System.out.println(map.firstEntry()); // a=1 88 | System.out.println(map.lastEntry()); // c=3 89 | 90 | // 翻转, keySet, values, entrySet 91 | System.out.println(map.reversed()); // {c=3, src=9, a=1} 92 | System.out.println(map.sequencedKeySet()); // [a, src, c] 93 | System.out.println(map.sequencedValues()); // [1, 9, 3] 94 | System.out.println(map.sequencedEntrySet()); // [a=1, src=9, c=3] 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/com/hepengju/java21/new02_record_patterns/_RecordPatterns.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java21.new02_record_patterns; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 记录模式 7 | */ 8 | public class _RecordPatterns { 9 | 10 | @Test 11 | public void testBase() { 12 | Point point = new Point(1, 2); 13 | printSumJava16(point); 14 | printSumJava21(point); 15 | } 16 | 17 | void printSumJava16(Object obj) { 18 | if (obj instanceof Point p) { 19 | int x = p.x(); 20 | int y = p.y(); 21 | System.out.println(x + y); 22 | } 23 | } 24 | 25 | void printSumJava21(Object obj) { 26 | if (obj instanceof Point (int x, int y)) { // 模式匹配解构(支持深层次嵌套) 27 | System.out.println(x + y); 28 | } 29 | } 30 | 31 | 32 | @Test 33 | public void testType() { 34 | Pair pair = new Pair(1, 2); 35 | 36 | if (pair instanceof Pair(String s, String t)) { 37 | System.out.println(s + ", " + t); 38 | } else { 39 | System.out.println("Not a pair of Strings: " + pair); // Not a pair of Strings: Pair[x=1, y=2] 40 | } 41 | } 42 | } 43 | 44 | 45 | record Point(int x, int y) {} 46 | record Pair(Object x, Object y) {} -------------------------------------------------------------------------------- /src/com/hepengju/java21/new03_switch_patterns/_SwitchPatterns.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java21.new03_switch_patterns; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * 为 switch 支持模式匹配 7 | * 8 | * @see com.hepengju.java12.new01_switch._Switch 9 | * @see com.hepengju.java13.new01_switch._Switch 10 | */ 11 | public class _SwitchPatterns { 12 | 13 | @Test 14 | public void testPatternMatchingSwitchStatement() { 15 | System.out.println(formatter(99)); 16 | System.out.println(formatter(999999999999999999L)); 17 | System.out.println(formatter(99.99)); 18 | System.out.println(formatter("java")); 19 | System.out.println(formatter(null)); 20 | System.out.println("-------------------------------"); 21 | 22 | System.out.println(formatterPatternSwitch(99)); 23 | System.out.println(formatterPatternSwitch(999999999999999999L)); 24 | System.out.println(formatterPatternSwitch(99.99)); 25 | System.out.println(formatterPatternSwitch("java")); 26 | System.out.println(formatterPatternSwitch(null)); 27 | } 28 | 29 | /** 30 | * 模式匹配 + Switch 写法 31 | */ 32 | String formatterPatternSwitch(Object o) { 33 | return switch (o) { 34 | case null -> null; // case null存在则匹配null的处理; 否则和之前版本一致, 抛出NPE异常(并不会进入default语句) 35 | case Integer i -> String.format("int %d", i); 36 | case Long l -> String.format("long %d", l); 37 | case Double d -> String.format("double %f", d); 38 | case String s -> String.format("String %s", s); 39 | default -> o.toString(); 40 | }; 41 | } 42 | 43 | /** 44 | * 模式匹配写法 45 | */ 46 | String formatter(Object o) { 47 | if (o == null) return null; 48 | 49 | String formatted = "unknown"; 50 | if (o instanceof Integer i) { 51 | formatted = String.format("int %d", i); 52 | } else if (o instanceof Long l) { 53 | formatted = String.format("long %d", l); 54 | } else if (o instanceof Double d) { 55 | formatted = String.format("double %f", d); 56 | } else if (o instanceof String s) { 57 | formatted = String.format("String %s", s); 58 | } 59 | return formatted; 60 | } 61 | 62 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 63 | /** 64 | * case ... when... 65 | */ 66 | @Test 67 | public void testCaseRefinement(){ 68 | testStringOld("YES"); 69 | testStringNew("YES"); 70 | } 71 | 72 | void testStringOld(String response) { 73 | switch (response) { 74 | case null -> { } 75 | case String s -> { 76 | if (s.equalsIgnoreCase("YES")) 77 | System.out.println("You got it"); 78 | else if (s.equalsIgnoreCase("NO")) 79 | System.out.println("Shame"); 80 | else 81 | System.out.println("Sorry?"); 82 | } 83 | } 84 | } 85 | 86 | void testStringNew(String response) { 87 | switch (response) { 88 | case null -> { } 89 | case String s when s.equalsIgnoreCase("YES") -> System.out.println("You got it"); 90 | case String s when s.equalsIgnoreCase("NO") -> System.out.println("Shame"); 91 | case String s -> System.out.println("Sorry?"); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/com/hepengju/java21/new04_visual_threads/_VirtualThread.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.java21.new04_visual_threads; 2 | 3 | 4 | import org.junit.Test; 5 | 6 | import java.time.Duration; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.ThreadFactory; 9 | import java.util.stream.IntStream; 10 | 11 | /** 12 | * 虚拟线程:协程,轻量级线程 13 | * 14 | *
15 |  *     1. 永远不要池化虚拟线程: 线程池和所有资源池一样,旨在共享昂贵的资源,但虚拟线程并不昂贵,而且永远不需要将它们池化
16 |  *     2. 虚拟线程永远是守护线程, Thread.setDaemon(boolean) 不能修改其为非守护线程
17 |  *     3. 虚拟线程有固定的优先级 Thread.NORM_PRIORITY, Thread.setPriority(int)对虚拟线程没有影响
18 |  *     4. 观察虚拟线程: jcmd  Thread.dump_to_file -format=json 
19 |  *
20 |  *     x. SpringBoot3.2开启支持虚拟线程: spring.threads.virtual.enabled=true 可开启虚拟线程
21 |  *          1)Tomcat/Jetty会使用虚拟线程处理请求
22 |  *          2)Blocking Execution with Spring WebFlux 会使用虚拟线程
23 |  *          3)Task Execution  会使用虚拟线程
24 |  *          4)Task Scheduling 会使用虚拟线程
25 |  *          5)spring.main.keep-alive=true,会开启一个平台线程,保证jvm不退出(因为虚拟线程都是守护线程)
26 |  *          6)其他技术集成: RabbitMQ Listener, Kafka Listener, Spring Data Redis的ClusterCommandExecutor等也会使用虚拟线程
27 |  * 
28 | * 29 | * @see Java下一代高并发技术——虚拟线程 30 | * @see SpringBoot3.2发行说明 31 | */ 32 | public class _VirtualThread { 33 | 34 | /** 35 | * 使用Executors创建虚拟线程 36 | */ 37 | @Test 38 | public void testExecutors() { 39 | try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { 40 | IntStream.range(0, 1_0000).forEach(i -> { 41 | executor.submit(() -> { 42 | Thread.sleep(Duration.ofSeconds(1)); 43 | return i; 44 | }); 45 | }); 46 | } 47 | // executor.close() is called implicitly, and waits 48 | } 49 | 50 | /** 51 | * Thread的新增api用于创建虚拟线程 52 | */ 53 | @Test 54 | public void testThread() throws InterruptedException { 55 | // Thread.Builder 56 | Thread.ofPlatform().name("platform thread").start(() -> System.out.println("我是平台线程")); 57 | Thread.ofVirtual().name("virtual thread").start(() -> System.out.println("我是虚拟线程")); 58 | 59 | // 虚拟线程工厂 60 | ThreadFactory factory = Thread.ofVirtual().factory(); 61 | factory.newThread(() -> System.out.println("虚拟线程工厂创建的虚拟线程")); 62 | 63 | // Thread静态方法启动虚拟线程 64 | Thread.startVirtualThread(() -> System.out.println("Thread静态方法启动虚拟线程")); 65 | 66 | // 新增Duration作为参数 67 | Thread.sleep(Duration.ofSeconds(1)); 68 | 69 | // join也新增duration作为参数,新增final方法threadId 70 | Thread thread = Thread.currentThread(); 71 | thread.join(Duration.ofSeconds(1)); 72 | thread.threadId(); 73 | thread.isVirtual(); 74 | System.out.println("threadId: " + thread.threadId() + ", isVirtual: " + thread.isVirtual()); 75 | } 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/com/hepengju/java21/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java21的新特性 3 | * 4 | *
 5 |  *      430: String Templates (Preview)                           字符串模板(预览)
 6 |  *      431: Sequenced Collections                                有序集合
 7 |  *      439: Generational ZGC                                     分代ZGC
 8 |  *      440: Record Patterns                                      记录模式
 9 |  *      441: Pattern Matching for switch                          switch模式匹配
10 |  *      442: Foreign Function & Memory API (Third Preview)        外部函数和内存API(第三次预览)
11 |  *      443: Unnamed Patterns and Variables (Preview)             未命名模式和变量(预览)
12 |  *      444: Virtual Threads                                      虚拟线程
13 |  *      445: Unnamed Classes and Instance Main Methods (Preview)  未命名类和实例main方法
14 |  *      446: Scoped Values (Preview)                              范围值(预览)
15 |  *      448: Vector API (Sixth Incubator)                         矢量API(第六次孵化)
16 |  *      449: Deprecate the Windows 32-bit x86 Port for Removal    弃用 Windows 32 位 x86 端口以进行删除
17 |  *      451: Prepare to Disallow the Dynamic Loading of Agents    准备禁止动态加载代理
18 |  *      452: Key Encapsulation Mechanism API                      用于密钥封装机制的 API
19 |  *      453: Structured Concurrency (Preview)                     结构化并发(预览)
20 |  * 
21 | * 22 | * @see OpenJDK21 23 | * @see OracleJDK21 24 | * 25 | * @author hepengju 26 | */ 27 | package com.hepengju.java21; -------------------------------------------------------------------------------- /src/com/hepengju/java22/new01_unnamed_variables/_UnnamedVariables.java: -------------------------------------------------------------------------------- 1 | //package com.hepengju.java22.new01_unnamed_variables; 2 | // 3 | //import java.util.ArrayDeque; 4 | //import java.util.Queue; 5 | // 6 | ///** 7 | // * 未命名变量与模式 8 | // */ 9 | //public class _UnnamedVariables { 10 | // 11 | // // 使用未命名变量的增强 for 循环 12 | // int count(Iterable orders) { 13 | // int total = 0; 14 | // for (Order _ : orders) { // 使用未命名变量 15 | // total++; 16 | // } 17 | // return total; 18 | // } 19 | // 20 | // // 在 while 循环中使用未命名变量 21 | // void other() { 22 | // // 在 while 循环中使用未命名变量 23 | // Queue q = new ArrayDeque<>(); 24 | // while (q.size() >= 3) { 25 | // var x = q.remove(); 26 | // var _ = q.remove(); // 使用未命名变量 27 | // var _ = q.remove(); // 使用未命名变量 28 | // } 29 | // 30 | // // 使用未命名变量的 catch 块 31 | // String s = ""; 32 | // try { 33 | // int i = Integer.parseInt(s); 34 | // } catch (NumberFormatException _) { // 使用未命名变量 35 | // System.out.println("Bad number: " + s); 36 | // } 37 | // 38 | // // 在 try-with-resources 语句中使用未命名变量 39 | // // try (var _ = ScopedContext.acquire()) { // 使用未命名变量 40 | // // } 41 | // 42 | // // 使用未命名变量的 lambda 表达式 43 | // // ...stream.collect(Collectors.toMap(String::toUpperCase, _ -> "NODATA")) // 使用未命名变量 44 | // 45 | // // 使用未命名模式变量的 switch 语句 46 | // // switch (ball) { 47 | // // case RedBall _ -> process(ball); 48 | // // case BlueBall _ -> process(ball); 49 | // // case GreenBall _ -> stopProcessing(); 50 | // // } 51 | // 52 | // // 使用未命名模式的 instanceof 检查 53 | // // if (r instanceof ColoredPoint(Point(int x, _), _)) { // 未使用的组件使用未命名模式 54 | // // } 55 | // } 56 | //} 57 | // 58 | -------------------------------------------------------------------------------- /src/com/hepengju/java22/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Java22的新特性 3 | * 4 | *
 5 |  *      423: Region Pinning for G1                                G1区域引入
 6 |  *      447: Statements before super(...) (Preview)               在 super(...) 之前的语句(预览版)
 7 |  *      454: Foreign Function & Memory API                        外来函数与内存 API
 8 |  *      456: Unnamed Variables & Patterns                         未命名变量与模式
 9 |  *      457: Class-File API (Preview)                             类文件 API(预览版)
10 |  *      458: Launch Multi-File Source-Code Programs               启动多文件源代码程序
11 |  *      459: String Templates (Second Preview)                    字符串模板(第二次预览版)
12 |  *      460: Vector API (Seventh Incubator)                       向量 API(第七个孵化版)
13 |  *      461: Stream Gatherers (Preview)                           流收集器(预览版)
14 |  *      462: Structured Concurrency (Second Preview)              结构化并发(第二次预览版)
15 |  *      463: Implicitly Declared Classes and Instance Main Methods (Second Preview)  隐式声明的类和实例主方法(第二次预览版)
16 |  *      464: Scoped Values (Second Preview)                       作用域值(第二次预览版)
17 |  * 
18 | * 19 | * @see OpenJDK22 20 | * @see OracleJDK22 21 | * 22 | * @author hepengju 23 | */ 24 | package com.hepengju.java22; -------------------------------------------------------------------------------- /src/com/hepengju/jvm/JVM00Util.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.jvm; 2 | 3 | //import ch.qos.logback.core.util.FileSize; 4 | 5 | /** 6 | * JVM测试的工具类 7 | */ 8 | public class JVM00Util { 9 | 10 | /** 11 | * 打印运行时内存 12 | */ 13 | public static void printMemory(String message){ 14 | Runtime runtime = Runtime.getRuntime(); 15 | if(message != null) System.out.println(message); 16 | System.out.println("Max : " + getReadSize(runtime.maxMemory())); 17 | System.out.println("Free : " + getReadSize(runtime.freeMemory())); 18 | System.out.println("Total: " + getReadSize(runtime.totalMemory())); 19 | } 20 | 21 | public static void printMemory(){ 22 | printMemory(null); 23 | } 24 | 25 | /** 26 | * 人类可读的数字 27 | */ 28 | public static String getReadSize(long size){ 29 | //return new FileSize(size).toString(); 30 | return String.valueOf(size); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/com/hepengju/jvm/JVM02Heap.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.jvm; 2 | 3 | import static com.hepengju.jvm.JVM00Util.printMemory; 4 | 5 | /** 6 | * JVM虚拟机参数: 堆 7 | * 8 | *
 9 |  *     -Xms 启动时初始化堆大小
10 |  *     -Xmx 最大的堆大小
11 |  *     -Xmn 设置新生代大小, 一般新生代设置为整个堆空间的1/3与1/4之间
12 |  *
13 |  *     -XX:SurvivorRatio                  设置新生代中的eden区/from区或eden区/to区的比例
14 |  *     -XX:NewRaito                       设置老年代/新生代的比例
15 |  *     -XX:+HeapDumpOnOutOfMemoryError    设置OOM异常时打印dump文件
16 |  *     -XX:HeapDumpPath                   设置OOM异常时dump文件的路径
17 | 
18 |  * 
19 | */ 20 | public class JVM02Heap { 21 | public static void main(String[] args) { 22 | // -Xlog:gc -Xlog:gc* -XX:+UseSerialGC -Xms5M -Xmx10M 23 | 24 | printMemory(); 25 | 26 | byte[] buf1 = new byte[1*1024*1024]; 27 | printMemory("分配1M内存"); 28 | 29 | byte[] buf2 = new byte[4*1024*1024]; 30 | printMemory("分配4M内存"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/com/hepengju/jvm/JVM03Stack.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.jvm; 2 | 3 | /** 4 | * JVM虚拟机参数: 栈 5 | * 6 | *
 7 |  *     -Xss 指定线程的最大栈空间, 也决定了函数可调用的最大深度
 8 |  * 
9 | */ 10 | public class JVM03Stack { 11 | } 12 | -------------------------------------------------------------------------------- /src/com/hepengju/jvm/JVM04Perm.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.jvm; 2 | 3 | /** 4 | * JVM虚拟机参数: 方法区 --> 元空间 5 | * 6 | *
 7 |  *    JDK1.8之前
 8 |  *     -XX:PermSize     设置初始化方法区的大小
 9 |  *     -XX:MaxPermSize  设置方法区(永久区)的大小, 避免永久区内存溢出, 默认为64M
10 |  *
11 |  *    JDK1.8之后
12 |  *
13 |  *
14 |  * 
15 | */ 16 | public class JVM04Perm { 17 | } 18 | -------------------------------------------------------------------------------- /src/com/hepengju/jvm/JVM05DirectMemory.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.jvm; 2 | 3 | /** 4 | * JVM虚拟机参数: 直接内存 5 | * 6 | *
 7 |  *      -XX:MaxDirectMemorySize 设置最大直接内存大小, 默认为最大堆空间即-Xmx
 8 |  * 
9 | */ 10 | public class JVM05DirectMemory { 11 | } 12 | -------------------------------------------------------------------------------- /src/com/hepengju/jvm/JVM06TLAB.java: -------------------------------------------------------------------------------- 1 | package com.hepengju.jvm; 2 | 3 | /** 4 | * JVM虚拟机参数: TLAB区 5 | * 6 | *
 7 |  *     -XX:MaxTenuringThreshold     设置经过多少次GC晋升老年代, 默认为15
 8 |  *     -XX:PreTenureSizeThreshold   设置超过多大的对象直接晋升老年代
 9 |  *
10 |  *     -XX:+UseTLAB                 使用TLAB(默认)
11 |  *     -XX:+TLABSize                设置TLAB大小
12 |  *     -XX:TLABRefillWasteFraction  设置进入TLAB空间的单个对象大小, 比例值, 默认为64, 即如果对象大于整个空间的1/64则在堆创建对象
13 |  *     -XX:+PrintTLAB               查看TLAB信息
14 |  *     -XX:ResizeTLAB               自动调整TLABRefillWasteFraction阈值
15 |  *     -XX:-DoEscapeAyalysis        (加上此参数, 才能在控制台查看TLAB信息)
16 |  * 
17 | */ 18 | public class JVM06TLAB { 19 | } 20 | -------------------------------------------------------------------------------- /src/com/hepengju/whynew/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Java新特性的引入示例 4 | * 5 | * @author hepengju 6 | * 7 | */ 8 | package com.hepengju.whynew; --------------------------------------------------------------------------------