• jdk7和8的一些新特性介绍


    jdk7和8的一些新特性介绍

    Java代码  收藏代码
    1. 本文是我学习了解了jdk7和jdk8的一些新特性的一些资料,有兴趣的大家可以浏览下下面的内容。  
    2. 官方文档:http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html  
    3.   
    4. 在jdk7的新特性方面主要有下面几方面的增强:  
    5.   
    6. 1.jdk7语法上  
    7.   
    8.    1.1二进制变量的表示,支持将整数类型用二进制来表示,用0b开头。  
    9.   
    10.    // 所有整数 int, short,long,byte都可以用二进制表示  
    11.     // An 8-bit 'byte' value:  
    12.     byte aByte = (byte) 0b00100001;  
    13.   
    14.     // A 16-bit 'short' value:  
    15.     short aShort = (short) 0b1010000101000101;  
    16.   
    17.     // Some 32-bit 'int' values:  
    18.     intanInt1 = 0b10100001010001011010000101000101;  
    19.     intanInt2 = 0b101;  
    20.     intanInt3 = 0B101; // The B can be upper or lower case.  
    21.   
    22.     // A 64-bit 'long' value. Note the "L" suffix:  
    23.     long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;  
    24.   
    25.     // 二进制在数组等的使用  
    26.     final int[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001,  
    27.     0b00010011, 0b00100110, 0b01001100, 0b10011000 };  
    28.   
    29. 1.2  Switch语句支持string类型   
    30.   
    31.        public static String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {  
    32.          String typeOfDay;  
    33.          switch (dayOfWeekArg) {  
    34.              case "Monday":  
    35.                  typeOfDay = "Start of work week";  
    36.                  break;  
    37.              case "Tuesday":  
    38.              case "Wednesday":  
    39.              case "Thursday":  
    40.                  typeOfDay = "Midweek";  
    41.                  break;  
    42.              case "Friday":  
    43.                  typeOfDay = "End of work week";  
    44.                  break;  
    45.              case "Saturday":  
    46.              case "Sunday":  
    47.                  typeOfDay = "Weekend";  
    48.                  break;  
    49.              default:  
    50.                  throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);  
    51.          }  
    52.          return typeOfDay;  
    53.     }   
    54.   
    55. 1.3 Try-with-resource语句   
    56.     
    57.   注意:实现java.lang.AutoCloseable接口的资源都可以放到try中,跟final里面的关闭资源类似; 按照声明逆序关闭资源 ;Try块抛出的异常通过Throwable.getSuppressed获取   
    58.   
    59.     try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);  
    60.     java.io.BufferedWriter writer = java.nio.file.Files   
    61.     .newBufferedWriter(outputFilePath, charset)) {  
    62.     // Enumerate each entry  
    63.     for (java.util.Enumeration entries = zf.entries(); entries  
    64.     .hasMoreElements();) {  
    65.     // Get the entry name and write it to the output file  
    66.     String newLine = System.getProperty("line.separator");  
    67.     String zipEntryName = ((java.util.zip.ZipEntry) entries  
    68.     .nextElement()).getName() + newLine;  
    69.     writer.write(zipEntryName, 0, zipEntryName.length());  
    70.     }  
    71.     }  
    72.   
    73. 1.4 Catch多个异常 说明:Catch异常类型为final; 生成Bytecode 会比多个catch小; Rethrow时保持异常类型   
    74.   
    75.     public static void main(String[] args) throws Exception {  
    76.     try {  
    77.     testthrows();  
    78.     } catch (IOException | SQLException ex) {  
    79.     throw ex;  
    80.     }  
    81.     }  
    82.     public static void testthrows() throws IOException, SQLException {  
    83.     }  
    84.   
    85. 1.5 数字类型的下划线表示 更友好的表示方式,不过要注意下划线添加的一些标准,可以参考下面的示例  
    86.   
    87.     long creditCardNumber = 1234_5678_9012_3456L;  
    88.     long socialSecurityNumber = 999_99_9999L;  
    89.     float pi = 3.14_15F;  
    90.     long hexBytes = 0xFF_EC_DE_5E;  
    91.     long hexWords = 0xCAFE_BABE;  
    92.     long maxLong = 0x7fff_ffff_ffff_ffffL;  
    93.     byte nybbles = 0b0010_0101;  
    94.     long bytes = 0b11010010_01101001_10010100_10010010;   
    95.     //float pi1 = 3_.1415F;      // Invalid; cannot put underscores adjacent to a decimal point  
    96.     //float pi2 = 3._1415F;      // Invalid; cannot put underscores adjacent to a decimal point  
    97.     //long socialSecurityNumber1= 999_99_9999_L;         // Invalid; cannot put underscores prior to an L suffix   
    98.     //int x1 = _52;              // This is an identifier, not a numeric literal  
    99.     int x2 = 5_2;              // OK (decimal literal)  
    100.     //int x3 = 52_;              // Invalid; cannot put underscores at the end of a literal  
    101.     int x4 = 5_______2;        // OK (decimal literal)   
    102.     //int x5 = 0_x52;            // Invalid; cannot put underscores in the 0x radix prefix  
    103.     //int x6 = 0x_52;            // Invalid; cannot put underscores at the beginning of a number  
    104.     int x7 = 0x5_2;            // OK (hexadecimal literal)  
    105.     //int x8 = 0x52_;            // Invalid; cannot put underscores at the end of a number   
    106.     int x9 = 0_52;             // OK (octal literal)  
    107.     int x10 = 05_2;            // OK (octal literal)  
    108.     //int x11 = 052_;            // Invalid; cannot put underscores at the end of a number   
    109.     1.6 泛型实例的创建可以通过类型推断来简化 可以去掉后面new部分的泛型类型,只用<>就可以了。  
    110.       //使用泛型前   
    111.     List strList = new ArrayList();   
    112.     List<String> strList4 = new ArrayList<String>();   
    113.     List<Map<String, List<String>>> strList5 =  new ArrayList<Map<String, List<String>>>();  
    114.   
    115.        
    116.     //编译器使用尖括号 (<>) 推断类型   
    117.     List<String> strList0 = new ArrayList<String>();   
    118.     List<Map<String, List<String>>> strList1 =  new ArrayList<Map<String, List<String>>>();   
    119.     List<String> strList2 = new ArrayList<>();   
    120.     List<Map<String, List<String>>> strList3 = new ArrayList<>();  
    121.     List<String> list = new ArrayList<>();  
    122.     list.add("A");  
    123.       // The following statement should fail since addAll expects  
    124.       // Collection<? extends String>  
    125.     //list.addAll(new ArrayList<>());   
    126.   
    127. 1.7在可变参数方法中传递非具体化参数,改进编译警告和错误   
    128.   
    129. Heap pollution 指一个变量被指向另外一个不是相同类型的变量。例如  
    130.   
    131.     List l = new ArrayList<Number>();  
    132.     List<String> ls = l;       // unchecked warning  
    133.     l.add(0, new Integer(42)); // another unchecked warning  
    134.     String s = ls.get(0);      // ClassCastException is thrown  
    135.     Jdk7:  
    136.     public static <T> void addToList (List<T> listArg, T... elements) {  
    137.     for (T x : elements) {  
    138.     listArg.add(x);  
    139.     }  
    140.     }  
    141.     你会得到一个warning  
    142.     warning: [varargs] Possible heap pollution from parameterized vararg type  
    143.     要消除警告,可以有三种方式  
    144.     1.加 annotation @SafeVarargs   
    145.     2.加 annotation @SuppressWarnings({"unchecked", "varargs"})  
    146.     3.使用编译器参数 –Xlint:varargs;  
    147.   
    148.   1.8 信息更丰富的回溯追踪 就是上面try中try语句和里面的语句同时抛出异常时,异常栈的信息  
    149.   
    150.     java.io.IOException    
    151.     §?      at Suppress.write(Suppress.java:19)    
    152.     §?      at Suppress.main(Suppress.java:8)    
    153.     §?      Suppressed:  java.io.IOException   
    154.     §?          at Suppress.close(Suppress.java:24)   
    155.     §?          at Suppress.main(Suppress.java:9)    
    156.     §?      Suppressed:  java.io.IOException   
    157.     §?          at  Suppress.close(Suppress.java:24)    
    158.     §?          at  Suppress.main(Suppress.java:9)   
    159.        
    160.   
    161. 2. NIO2的一些新特性  
    162.       
    163.     1.java.nio.file 和java.nio.file.attribute包 支持更详细属性,比如权限,所有者   
    164.     2.  symbolic and hard links支持   
    165.     3. Path访问文件系统,Files支持各种文件操作   
    166.     4.高效的访问metadata信息   
    167.     5.递归查找文件树,文件扩展搜索   
    168.     6.文件系统修改通知机制   
    169.     7.File类操作API兼容   
    170.     8.文件随机访问增强 mapping a region,locl a region,绝对位置读取   
    171.     9. AIO Reactor(基于事件)和Proactor   
    172.   
    173.   下面列一些示例:  
    174.   
    175. 2.1IO and New IO 监听文件系统变化通知   
    176.   
    177. 通过FileSystems.getDefault().newWatchService()获取watchService,然后将需要监听的path目录注册到这个watchservice中,对于这个目录的文件修改,新增,删除等实践可以配置,然后就自动能监听到响应的事件。  
    178.   
    179.     private WatchService watcher;   
    180.     public TestWatcherService(Path path) throws IOException {  
    181.     watcher = FileSystems.getDefault().newWatchService();  
    182.     path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);  
    183.     }   
    184.     public void handleEvents() throws InterruptedException {  
    185.     while (true) {  
    186.     WatchKey key = watcher.take();  
    187.     for (WatchEvent<?> event : key.pollEvents()) {  
    188.     WatchEvent.Kind kind = event.kind();  
    189.     if (kind == OVERFLOW) {// 事件可能lost or discarded  
    190.     continue;  
    191.     }  
    192.     WatchEvent<Path> e = (WatchEvent<Path>) event;  
    193.     Path fileName = e.context();  
    194.     System.out.printf("Event %s has happened,which fileName is %s%n",kind.name(), fileName);  
    195.     }  
    196.     if (!key.reset()) {  
    197.     break;  
    198.     }  
    199.   
    200. 2.2 IO and New IO遍历文件树 ,通过继承SimpleFileVisitor类,实现事件遍历目录树的操作,然后通过Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);这个API来遍历目录树  
    201.   
    202.     private void workFilePath() {  
    203.     Path listDir = Paths.get("/tmp"); // define the starting file   
    204.     ListTree walk = new ListTree();  
    205.     …Files.walkFileTree(listDir, walk);…  
    206.     // 遍历的时候跟踪链接  
    207.     EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);  
    208.     try {  
    209.     Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);  
    210.     } catch (IOException e) {  
    211.     System.err.println(e);  
    212.     }  
    213.     class ListTree extends SimpleFileVisitor<Path> {// NIO2 递归遍历文件目录的接口   
    214.     @Override  
    215.     public FileVisitResult postVisitDirectory(Path dir, IOException exc) {  
    216.     System.out.println("Visited directory: " + dir.toString());  
    217.     return FileVisitResult.CONTINUE;  
    218.     }   
    219.     @Override  
    220.     public FileVisitResult visitFileFailed(Path file, IOException exc) {  
    221.     System.out.println(exc);  
    222.     return FileVisitResult.CONTINUE;  
    223.     }  
    224.     }  
    225.   
    226.   
    227. 2.3 AIO异步IO 文件和网络 异步IO在java   
    228.  NIO2实现了,都是用AsynchronousFileChannel,AsynchronousSocketChanne等实现,关于同步阻塞IO,同步非阻塞IO,异步阻塞IO和异步非阻塞IO在ppt的这页上下面备注有说明,有兴趣的可以深入了解下。Java NIO2中就实现了操作系统的异步非阻塞IO。  
    229.   
    230.     // 使用AsynchronousFileChannel.open(path, withOptions(),    
    231.         // taskExecutor))这个API对异步文件IO的处理    
    232.         public static void asyFileChannel2() {    
    233.             final int THREADS = 5;    
    234.             ExecutorService taskExecutor = Executors.newFixedThreadPool(THREADS);    
    235.             String encoding = System.getProperty("file.encoding");    
    236.             List<Future<ByteBuffer>> list = new ArrayList<>();    
    237.             int sheeps = 0;    
    238.             Path path = Paths.get("/tmp",    
    239.                     "store.txt");    
    240.             try (AsynchronousFileChannel asynchronousFileChannel = AsynchronousFileChannel    
    241.                     .open(path, withOptions(), taskExecutor)) {    
    242.                 for (int i = 0; i < 50; i++) {    
    243.                     Callable<ByteBuffer> worker = new Callable<ByteBuffer>() {    
    244.                         @Override    
    245.                         public ByteBuffer call() throws Exception {    
    246.                             ByteBuffer buffer = ByteBuffer    
    247.                                     .allocateDirect(ThreadLocalRandom.current()    
    248.                                             .nextInt(100, 200));    
    249.                             asynchronousFileChannel.read(buffer, ThreadLocalRandom    
    250.     ……  
    251.   
    252.           
    253. 3. JDBC 4.1  
    254.   
    255. 3.1.可以使用try-with-resources自动关闭Connection, ResultSet, 和 Statement资源对象   
    256.   
    257. 3.2. RowSet 1.1:引入RowSetFactory接口和RowSetProvider类,可以创建JDBC driver支持的各种 row sets,这里的rowset实现其实就是将sql语句上的一些操作转为方法的操作,封装了一些功能。  
    258.   
    259. 3.3. JDBC-ODBC驱动会在jdk8中删除   
    260.   
    261.     try (Statement stmt = con.createStatement()) {   
    262.      RowSetFactory aFactory = RowSetProvider.newFactory();  
    263.       CachedRowSet crs = aFactory.createCachedRowSet();  
    264.         
    265.      RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl", null);  
    266.     WebRowSet wrs = rsf.createWebRowSet();  
    267.     createCachedRowSet   
    268.     createFilteredRowSet   
    269.     createJdbcRowSet   
    270.     createJoinRowSet   
    271.     createWebRowSet   
    272.   
    273.   
    274. 4. 并发工具增强   
    275.   
    276. 4.1.fork-join   
    277.  最大的增强,充分利用多核特性,将大问题分解成各个子问题,由多个cpu可以同时解决多个子问题,最后合并结果,继承RecursiveTask,实现compute方法,然后调用fork计算,最后用join合并结果。  
    278.   
    279.     class Fibonacci extends RecursiveTask<Integer> {  
    280.     final int n;  
    281.     Fibonacci(int n) {  
    282.     this.n = n;  
    283.     }  
    284.     private int compute(int small) {  
    285.     final int[] results = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };  
    286.     return results[small];  
    287.     }  
    288.     public Integer compute() {  
    289.     if (n <= 10) {  
    290.     return compute(n);  
    291.     }  
    292.     Fibonacci f1 = new Fibonacci(n - 1);  
    293.     Fibonacci f2 = new Fibonacci(n - 2);  
    294.     System.out.println("fork new thread for " + (n - 1));  
    295.     f1.fork();  
    296.     System.out.println("fork new thread for " + (n - 2));  
    297.     f2.fork();  
    298.     return f1.join() + f2.join();  
    299.     }  
    300.     }   
    301.   
    302.  4.2.ThreadLocalRandon 并发下随机数生成类,保证并发下的随机数生成的线程安全,实际上就是使用threadlocal  
    303.   
    304.     final int MAX = 100000;  
    305.     ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();  
    306.     long start = System.nanoTime();  
    307.     for (int i = 0; i < MAX; i++) {  
    308.     threadLocalRandom.nextDouble();  
    309.     }  
    310.     long end = System.nanoTime() - start;  
    311.     System.out.println("use time1 : " + end);  
    312.     long start2 = System.nanoTime();  
    313.     for (int i = 0; i < MAX; i++) {  
    314.     Math.random();  
    315.     }  
    316.     long end2 = System.nanoTime() - start2;  
    317.     System.out.println("use time2 : " + end2);   
    318.   
    319.          
    320. 4.3. phaser 类似cyclebarrier和countdownlatch,不过可以动态添加资源减少资源  
    321.   
    322.      void runTasks(List<Runnable> tasks) {  
    323.     final Phaser phaser = new Phaser(1); // "1" to register self  
    324.     // create and start threads  
    325.     for (final Runnable task : tasks) {  
    326.     phaser.register();  
    327.     new Thread() {  
    328.     public void run() {  
    329.     phaser.arriveAndAwaitAdvance(); // await all creation  
    330.     task.run();  
    331.     }  
    332.     }.start();  
    333.     }  
    334.     // allow threads to start and deregister self  
    335.     phaser.arriveAndDeregister();  
    336.     }   
    337.   
    338. 5. Networking增强   
    339.   
    340. 新增URLClassLoader close方法,可以及时关闭资源,后续重新加载class文件时不会导致资源被占用或者无法释放问题  
    341. URLClassLoader.newInstance(new URL[]{}).close();  
    342. 新增Sockets Direct Protocol  
    343. 绕过操作系统的数据拷贝,将数据从一台机器的内存数据通过网络直接传输到另外一台机器的内存中   
    344.   
    345. 6. Multithreaded Custom Class Loaders    
    346.       
    347.     解决并发下加载class可能导致的死锁问题,这个是jdk1.6的一些新版本就解决了,jdk7也做了一些优化。有兴趣可以仔细从官方文档详细了解  
    348.   
    349. jdk7前:  
    350.     
    351.     Class Hierarchy:              
    352.       class A extends B  
    353.       class C extends D  
    354.     ClassLoader Delegation Hierarchy:  
    355.     Custom Classloader CL1:  
    356.       directly loads class A   
    357.       delegates to custom ClassLoader CL2 for class B  
    358.     Custom Classloader CL2:  
    359.       directly loads class C  
    360.       delegates to custom ClassLoader CL1 for class D  
    361.     Thread 1:  
    362.       Use CL1 to load class A (locks CL1)  
    363.         defineClass A triggers  
    364.           loadClass B (try to lock CL2)  
    365.     Thread 2:  
    366.       Use CL2 to load class C (locks CL2)  
    367.         defineClass C triggers  
    368.           loadClass D (try to lock CL1)  
    369.     Synchronization in the ClassLoader class wa   
    370.   
    371. jdk7  
    372.   
    373.     Thread 1:  
    374.       Use CL1 to load class A (locks CL1+A)  
    375.         defineClass A triggers  
    376.           loadClass B (locks CL2+B)  
    377.     Thread 2:  
    378.       Use CL2 to load class C (locks CL2+C)  
    379.         defineClass C triggers  
    380.           loadClass D (locks CL1+D)   
    381.   
    382.   
    383. 7. Security 增强   
    384.   
    385.     7.1.提供几种 ECC-based algorithms (ECDSA/ECDH) Elliptic Curve Cryptography (ECC)  
    386.     7.2.禁用CertPath Algorithm Disabling  
    387.     7.3. JSSE (SSL/TLS)的一些增强   
    388.   
    389. 8. Internationalization 增强 增加了对一些编码的支持和增加了一些显示方面的编码设置等  
    390.       
    391.     1. New Scripts and Characters from Unicode 6.0.0  
    392.     2. Extensible Support for ISO 4217 Currency Codes  
    393.     Currency类添加:        
    394.            getAvailableCurrencies   
    395.            getNumericCode   
    396.            getDisplayName   
    397.            getDisplayName(Locale)  
    398.     3. Category Locale Support  
    399.      getDefault(Locale.Category)FORMAT  DISPLAY   
    400.     4. Locale Class Supports BCP47 and UTR35  
    401.            UNICODE_LOCALE_EXTENSION  
    402.            PRIVATE_USE_EXTENSION  
    403.            Locale.Builder   
    404.            getExtensionKeys()  
    405.            getExtension(char)  
    406.            getUnicodeLocaleType(String  
    407.             ……  
    408.     5. New NumericShaper Methods  
    409.     NumericShaper.Range   
    410.     getShaper(NumericShaper.Range)   
    411.     getContextualShaper(Set<NumericShaper.Range>)……   
    412.   
    413.   
    414. 9.jvm方面的一些特性增强,下面这些特性有些在jdk6中已经存在,这里做了一些优化和增强。  
    415.   
    416. 1.Jvm支持非java的语言 invokedynamic 指令   
    417.   
    418. 2. Garbage-First Collector 适合server端,多处理器下大内存,将heap分成大小相等的多个区域,mark阶段检测每个区域的存活对象,compress阶段将存活对象最小的先做回收,这样会腾出很多空闲区域,这样并发回收其他区域就能减少停止时间,提高吞吐量。   
    419.   
    420. 3. HotSpot性能增强   
    421.     Tiered Compilation  -XX:+UseTieredCompilation 多层编译,对于经常调用的代码会直接编译程本地代码,提高效率  
    422.    Compressed Oops  压缩对象指针,减少空间使用  
    423.   Zero-Based Compressed Ordinary Object Pointers (oops) 进一步优化零基压缩对象指针,进一步压缩空间  
    424.   
    425. 4. Escape Analysis  逃逸分析,对于只是在一个方法使用的一些变量,可以直接将对象分配到栈上,方法执行完自动释放内存,而不用通过栈的对象引用引用堆中的对象,那么对于对象的回收可能不是那么及时。  
    426.   
    427. 5. NUMA Collector Enhancements    
    428.   
    429. NUMA(Non Uniform Memory Access),NUMA在多种计算机系统中都得到实现,简而言之,就是将内存分段访问,类似于硬盘的RAID,Oracle中的分簇   
    430.   
    431. 10. Java 2D Enhancements  
    432.   
    433.     1. XRender-Based Rendering Pipeline -Dsun.java2d.xrender=True  
    434.     2. Support for OpenType/CFF Fonts GraphicsEnvironment.getAvailableFontFamilyNames   
    435.     3. TextLayout Support for Tibetan Script  
    436.     4. Support for Linux Fonts  
    437.   
    438. 11. Swing Enhancements  
    439.   
    440.     1.  JLayer   
    441.     2.  Nimbus Look & Feel  
    442.     3.  Heavyweight and Lightweight Components  
    443.     4.  Shaped and Translucent Windows  
    444.     5.  Hue-Saturation-Luminance (HSL) Color Selection in JColorChooser Class  
    445.   
    446.   
    447.   
    448. 12. Jdk8 lambda表达式 最大的新增的特性,不过在很多动态语言中都已经原生支持。  
    449.   
    450. 原来这么写:  
    451.   
    452.     btn.setOnAction(new EventHandler<ActionEvent>() {   
    453.         @Override   
    454.         public void handle(ActionEvent event) {   
    455.             System.out.println("Hello World!");   
    456.         }   
    457.     });   
    458.          
    459. jdk8直接可以这么写:  
    460.   
    461.     btn.setOnAction(   
    462.         event -> System.out.println("Hello World!")   
    463.     );     
    464.          
    465. 更多示例:  
    466.      
    467.     public class Utils {   
    468.         public static int compareByLength(String in, String out){   
    469.             return in.length() - out.length();   
    470.         }   
    471.     }   
    472.   
    473.     public class MyClass {   
    474.         public void doSomething() {   
    475.             String[] args = new String[] {"microsoft","apple","linux","oracle"}   
    476.             Arrays.sort(args, Utils::compareByLength);   
    477.         }    
    478.     }    
    479.   
    480. 13.jdk8的一些其他特性,当然jdk8的增强功能还有很多,大家可以参考http://openjdk.java.net/projects/jdk8/  
    481.   
    482. 用Metaspace代替PermGen   
    483. 动态扩展,可以设置最大值,限制于本地内存的大小   
    484. Parallel array sorting 新APIArrays#parallelSort.  
    485.   
    486.     New Date & Time API  
    487.     Clock clock = Clock.systemUTC(); //return the current time based on your system clock and set to UTC.  
    488.   
    489.     Clock clock = Clock.systemDefaultZone(); //return time based on system clock zone   
    490.   
    491.     long time = clock.millis(); //time in milliseconds from January 1st, 1970   
    492.   
    493. 更多内容可以看看附件ppt,示例代码可以参考:https://github.com/zhwj184/jdk7-8demo  
  • 相关阅读:
    spring boot SpringApplication.run 执行过程
    算法 计算四则运算字符串结果
    算法 RingBuffer
    java BigDecimal 四舍五入
    算法 常用函数和近似
    java 多线程执行
    Java 三个线程依次输出ABC
    Java interrupt 中断
    java 垃圾收集器与内存分配策略
    软件项目与软件产品的区别
  • 原文地址:https://www.cnblogs.com/timssd/p/5523356.html
Copyright © 2020-2023  润新知