美文网首页Java
从Java5到Java12每个版本的新特性(1)

从Java5到Java12每个版本的新特性(1)

作者: 4ea0af17fd67 | 来源:发表于2018-12-02 21:05 被阅读2190次

    Java5的新特性

    • 泛型
    • 枚举
    • 装箱拆箱
    • 变长参数
    • 注解
    • foreach循环
    • 静态导入
    • 格式化
    • 线程框架/数据结构
    • Arrays工具类/StringBuilder/instrument

    1、泛型

    所谓类型擦除指的就是Java源码中的范型信息只允许停留在编译前期,而编译后的字节码文件中将不再保留任何的范型信息。也就是说,范型信息在编译时将会被全部删除,其中范型类型的类型参数则会被替换为Object类型,并在实际使用时强制转换为指定的目标数据类型。而C++中的模板则会在编译时将模板类型中的类型参数根据所传递的指定数据类型生成相对应的目标代码。

    Map<Integer, Integer> squares = new HashMap<Integer, Integer>();
    
    • 通配符类型:避免unchecked警告,问号表示任何类型都可以接受
    public void printList(List<?> list, PrintStream out) throws IOException {
        for (Iterator<?> i = list.iterator(); i.hasNext(); ) {
          out.println(i.next().toString());
        }
      }
    
    • 限制类型
    public static <A extends Number> double sum(Box<A> box1,Box<A> box2){
        double total = 0;
        for (Iterator<A> i = box1.contents.iterator(); i.hasNext(); ) {
          total = total + i.next().doubleValue();
        }
        for (Iterator<A> i = box2.contents.iterator(); i.hasNext(); ) {
          total = total + i.next().doubleValue();
        }
        return total;
      }
    

    2、枚举

    • EnumMap
    public void testEnumMap(PrintStream out) throws IOException {
        // Create a map with the key and a String message
        EnumMap<AntStatus, String> antMessages =
          new EnumMap<AntStatus, String>(AntStatus.class);
        // Initialize the map
        antMessages.put(AntStatus.INITIALIZING, "Initializing Ant...");
        antMessages.put(AntStatus.COMPILING,    "Compiling Java classes...");
        antMessages.put(AntStatus.COPYING,      "Copying files...");
        antMessages.put(AntStatus.JARRING,      "JARring up files...");
        antMessages.put(AntStatus.ZIPPING,      "ZIPping up files...");
        antMessages.put(AntStatus.DONE,         "Build complete.");
        antMessages.put(AntStatus.ERROR,        "Error occurred.");
        // Iterate and print messages
        for (AntStatus status : AntStatus.values() ) {
          out.println("For status " + status + ", message is: " +
                      antMessages.get(status));
        }
      }
    
    • switch枚举
    public String getDescription() {
        switch(this) {
          case ROSEWOOD:      return "Rosewood back and sides";
          case MAHOGANY:      return "Mahogany back and sides";
          case ZIRICOTE:      return "Ziricote back and sides";
          case SPRUCE:        return "Sitka Spruce top";
          case CEDAR:         return "Wester Red Cedar top";
          case AB_ROSETTE:    return "Abalone rosette";
          case AB_TOP_BORDER: return "Abalone top border";
          case IL_DIAMONDS:   
            return "Diamonds and squares fretboard inlay";
          case IL_DOTS:
            return "Small dots fretboard inlay";
          default: return "Unknown feature";
        }
      }
    

    3、Autoboxing与Unboxing

    将primitive类型转换成对应的wrapper类型:Boolean、Byte、Short、Character、Integer、Long、Float、Double

    public static void m1(Integer i){
            System.out.println("this is integer");
        }
        public static void m1(double d){
            System.out.println("this is double");
        }
    

    m1(1)输出的是double,方法匹配时线下兼容,不考虑boxing与unboxing。

    4、vararg

    private String print(Object... values) {
        StringBuilder sb = new StringBuilder();
        for (Object o : values) {
          sb.append(o.toString())
            .append(" ");
        }
        return sb.toString();
      }
    

    5、annotation

    • Inherited表示该注解是否对类的子类继承的方法等起作用
    @Documented
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    public @interface InProgress { }
    
    • 指定Target
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE,
             ElementType.METHOD, 
             ElementType.CONSTRUCTOR, 
             ElementType.ANNOTATION_TYPE})
    public @interface TODO { 
      String value();
    }
    
    • Target类型
    public enum ElementType {
        /** Class, interface (including annotation type), or enum declaration */
        TYPE,
        /** Field declaration (includes enum constants) */
        FIELD,
        /** Method declaration */
        METHOD,
        /** Parameter declaration */
        PARAMETER,
        /** Constructor declaration */
        CONSTRUCTOR,
        /** Local variable declaration */
        LOCAL_VARIABLE,
        /** Annotation type declaration */
        ANNOTATION_TYPE,
        /** Package declaration */
        PACKAGE
    }
    
    • rentation表示annotation是否保留在编译过的class文件中还是在运行时可读。
    public enum RetentionPolicy {
        /**
         * Annotations are to be discarded by the compiler.
         */
        SOURCE,
        /**
         * Annotations are to be recorded in the class file by the compiler
         * but need not be retained by the VM at run time.  This is the default
         * behavior.
         */
        CLASS,
        /**
         * Annotations are to be recorded in the class file by the compiler and
         * retained by the VM at run time, so they may be read reflectively.
         *
         * @see java.lang.reflect.AnnotatedElement
         */
        RUNTIME
    }
    
    • 通过反射获取元信息
    public class ReflectionTester {
      public ReflectionTester() {
      }
      public void testAnnotationPresent(PrintStream out) throws IOException {
        Class c = Super.class;
        boolean inProgress = c.isAnnotationPresent(InProgress.class);
        if (inProgress) {
          out.println("Super is In Progress");
        } else {
          out.println("Super is not In Progress");
        }
      }
      public void testInheritedAnnotation(PrintStream out) throws IOException {
        Class c = Sub.class;
        boolean inProgress = c.isAnnotationPresent(InProgress.class);
        if (inProgress) {
          out.println("Sub is In Progress");
        } else {
          out.println("Sub is not In Progress");
        }
      }
      public void testGetAnnotation(PrintStream out) 
        throws IOException, NoSuchMethodException {
        Class c = AnnotationTester.class;
        AnnotatedElement element = c.getMethod("calculateInterest", 
                                      float.class, float.class);
        GroupTODO groupTodo = element.getAnnotation(GroupTODO.class);
        String assignedTo = groupTodo.assignedTo();
        out.println("TODO Item on Annotation Tester is assigned to: '" + 
            assignedTo + "'");
      }
      public void printAnnotations(AnnotatedElement e, PrintStream out)
        throws IOException {
        out.printf("Printing annotations for '%s'%n%n", e.toString());
        Annotation[] annotations = e.getAnnotations();
        for (Annotation a : annotations) {
          out.printf("    * Annotation '%s' found%n", 
            a.annotationType().getName());
        }
      }
      public static void main(String[] args) {
        try {
          ReflectionTester tester = new ReflectionTester();
          tester.testAnnotationPresent(System.out);
          tester.testInheritedAnnotation(System.out);
          tester.testGetAnnotation(System.out);
          Class c = AnnotationTester.class;
          AnnotatedElement element = c.getMethod("calculateInterest", 
                                        float.class, float.class);      
          tester.printAnnotations(element, System.out);
        } catch (Exception e) {
          e.printStackTrace();
        } 
      }
    }
    

    6、for/in

    for/in循环办不到的事情:
    (1)遍历同时获取index
    (2)集合逗号拼接时去掉最后一个
    (3)遍历的同时删除元素

    7、静态import

    import static java.lang.System.err;
    import static java.lang.System.out;
    import java.io.IOException;
    import java.io.PrintStream;
    public class StaticImporter {
      public static void writeError(PrintStream err, String msg) 
        throws IOException {
    
        // Note that err in the parameter list overshadows the imported err
        err.println(msg); 
      }
      public static void main(String[] args) {
        if (args.length < 2) {
          err.println(
            "Incorrect usage: java com.oreilly.tiger.ch08 [arg1] [arg2]");
          return;
        }
        out.println("Good morning, " + args[0]);
        out.println("Have a " + args[1] + " day!");
        try {
          writeError(System.out, "Error occurred.");
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    

    8、格式化

    /**
     * java.text.DateFormat
     * java.text.SimpleDateFormat
     * java.text.MessageFormat
     * java.text.NumberFormat
     * java.text.ChoiceFormat
     * java.text.DecimalFormat
     */
    public class FormatTester {
        public static void printf() {
            //printf
            String filename = "this is a file";
            try {
                File file = new File(filename);
                FileReader fileReader = new FileReader(file);
                BufferedReader reader = new BufferedReader(fileReader);
                String line;
                int i = 1;
                while ((line = reader.readLine()) != null) {
                    System.out.printf("Line %d: %s%n", i++, line);
                }
            } catch (Exception e) {
                System.err.printf("Unable to open file named '%s': %s",
                        filename, e.getMessage());
            }
        }
        public static void stringFormat() {
            // Format a string containing a date.
            Calendar c = new GregorianCalendar(1995, MAY, 23);
            String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
            // -> s == "Duke's Birthday: May 23, 1995"
            System.out.println(s);
        }
        public static void formatter() {
            StringBuilder sb = new StringBuilder();
            // Send all output to the Appendable object sb
            Formatter formatter = new Formatter(sb, Locale.US);
            // Explicit argument indices may be used to re-order output.
            formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
            // -> " d  c  b  a"
            // Optional locale as the first argument can be used to get
            // locale-specific formatting of numbers.  The precision and width can be
            // given to round and align the value.
            formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
            // -> "e =    +2,7183"
            // The '(' numeric flag may be used to format negative numbers with
            // parentheses rather than a minus sign.  Group separators are
            // automatically inserted.
            formatter.format("Amount gained or lost since last statement: $ %(,.2f",
                    6217.58);
            // -> "Amount gained or lost since last statement: $ (6,217.58)"
        }
        public static void messageFormat() {
            String msg = "欢迎光临,当前({0})等待的业务受理的顾客有{1}位,请排号办理业务!";
            MessageFormat mf = new MessageFormat(msg);
            String fmsg = mf.format(new Object[]{new Date(), 35});
            System.out.println(fmsg);
        }
        public static void dateFormat(){
            String str = "2010-1-10 17:39:21";
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
            try {
                System.out.println(format.format(format.parse(str)));
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            formatter();
            stringFormat();
            messageFormat();
            dateFormat();
            printf();
        }
    }
    

    9、threading

    • uncaught exception
    public class BubbleSortThread extends Thread {
      private int[] numbers;
      public BubbleSortThread(int[] numbers) {
        setName("Simple Thread");
        setUncaughtExceptionHandler(
          new SimpleThreadExceptionHandler());
        this.numbers = numbers;
      }
      public void run() {
        int index = numbers.length;
        boolean finished = false;
        while (!finished) {
          index--;
          finished = true;
          for (int i=0; i<index; i++) {
            // Create error condition
            if (numbers[i+1] < 0) {
              throw new IllegalArgumentException(
                "Cannot pass negative numbers into this thread!");
            }
            if (numbers[i] > numbers[i+1]) {
              // swap
              int temp = numbers[i];
              numbers[i] = numbers[i+1];
              numbers[i+1] = temp;
              finished = false;
            }
          }
        }    
      }
    }
    class SimpleThreadExceptionHandler implements
        Thread.UncaughtExceptionHandler {
      public void uncaughtException(Thread t, Throwable e) {
        System.err.printf("%s: %s at line %d of %s%n",
            t.getName(), 
            e.toString(),
            e.getStackTrace()[0].getLineNumber(),
            e.getStackTrace()[0].getFileName());
      }
    }
    
    • blocking queue
    public class Producer extends Thread {
      private BlockingQueue q;
      private PrintStream out;
      public Producer(BlockingQueue q, PrintStream out) {
        setName("Producer");
        this.q = q;
        this.out = out;
      }
      public void run() {
        try {
          while (true) {
            q.put(produce());
          }
        } catch (InterruptedException e) {
          out.printf("%s interrupted: %s", getName(), e.getMessage());
        }
      }
      private String produce() {
        while (true) {
          double r = Math.random();
          // Only goes forward 1/10 of the time
          if ((r*100) < 10) {
            String s = String.format("Inserted at %tc", new Date());
            return s;
          }
        }
      }
    }
    
    • 线程池

    著名的JUC类库。

    • 每次提交任务时,如果线程数还没达到coreSize就创建新线程并绑定该任务。 所以第coreSize次提交任务后线程总数必达到coreSize,不会重用之前的空闲线程。
    • 线程数达到coreSize后,新增的任务就放到工作队列里,而线程池里的线程则努力的使用take()从工作队列里拉活来干。
    • 如果队列是个有界队列,又如果线程池里的线程不能及时将任务取走,工作队列可能会满掉,插入任务就会失败,此时线程池就会紧急的再创建新的临时线程来补救。
    • 临时线程使用poll(keepAliveTime,timeUnit)来从工作队列拉活,如果时候到了仍然两手空空没拉到活,表明它太闲了,就会被解雇掉。
    • 如果core线程数+临时线程数 >maxSize,则不能再创建新的临时线程了,转头执行RejectExecutionHanlder。默认的AbortPolicy抛RejectedExecutionException异常,其他选择包括静默放弃当前任务(Discard),放弃工作队列里最老的任务(DisacardOldest),或由主线程来直接执行(CallerRuns),或你自己发挥想象力写的一个。

    10、其他

    • Arrays
    Arrays.sort(myArray);
    Arrays.toString(myArray)
    Arrays.binarySearch(myArray, 98)
    Arrays.deepToString(ticTacToe)
    Arrays.deepEquals(ticTacToe, ticTacToe3)
    
    • Queue

    避开集合的add/remove操作,使用offer、poll操作(不抛异常)

    Queue q = new LinkedList(); 采用它来实现queue
    
    • Override返回类型

    支持协变返回

    • 单线程StringBuilder

    线程不安全,在单线程下替换string buffer提高性能

    • java.lang.instrument

    参考

    Java6新特性

    • JSR223脚本引擎
    • JSR199--Java Compiler API
    • JSR269--Pluggable Annotation Processing API
    • 支持JDBC4.0规范
    • JAX-WS 2.0规范

    1、JSR223脚本引擎

    Scripting for the Java Platform

    • 基本使用
    public class BasicScripting {
        public void greet() throws ScriptException {
            ScriptEngineManager manager = new ScriptEngineManager();
            //支持通过名称、文件扩展名、MIMEtype查找
            ScriptEngine engine = manager.getEngineByName("JavaScript");
    //        engine = manager.getEngineByExtension("js");
    //        engine = manager.getEngineByMimeType("text/javascript");
            if (engine == null) {
                throw new RuntimeException("找不到JavaScript语言执行引擎。");
            }
            engine.eval("println('Hello!');");
        }
        public static void main(String[] args) {
            try {
                new BasicScripting().greet();
            } catch (ScriptException ex) {
                Logger.getLogger(BasicScripting.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    • 绑定上下文
    public class ScriptContextBindings extends JsScriptRunner {
        public void scriptContextBindings() throws ScriptException {
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            Bindings bindings1 = engine.createBindings();
            bindings1.put("name", "Alex");
            context.setBindings(bindings1, ScriptContext.GLOBAL_SCOPE);
            Bindings bindings2 = engine.createBindings();
            bindings2.put("name", "Bob");
            context.setBindings(bindings2, ScriptContext.ENGINE_SCOPE);
            engine.eval("println(name);");
        }
        public void useScriptContextValues() throws ScriptException {
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
            bindings.put("name", "Alex");
            engine.eval("println(name);");
        }
        public void attributeInBindings() throws ScriptException {
            ScriptEngine engine = getJavaScriptEngine();
            ScriptContext context = engine.getContext();
            context.setAttribute("name", "Alex", ScriptContext.GLOBAL_SCOPE);
            engine.eval("println(name);");
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws ScriptException {
            ScriptContextBindings scb = new ScriptContextBindings();
            scb.scriptContextBindings();
            scb.useScriptContextValues();
            scb.attributeInBindings();
        }
    }
    

    2、JSR199--Java Compiler API

    public class JavaCompilerAPICompiler {
        public void compile(Path src, Path output) throws IOException {
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
                Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(src.toFile());
                Iterable<String> options = Arrays.asList("-d", output.toString());
                JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, options, null, compilationUnits);
                boolean result = task.call();
            }
        }
    }
    

    3、JSR269--Pluggable Annotation Processing API

    一部分是进行注解处理的javax.annotation.processing,另一部分是对程序的静态结构进行建模的javax.lang.model

    4、其他

    • 支持JDBC4.0规范
    • JAX-WS 2.0规范(包括JAXB 2.0)
    • 轻量级HttpServer

    参考

    Java7新特性

    • suppress异常(新语法)
    • 捕获多个异常(新语法)
    • try-with-resources(新语法)
    • JSR341-Expression Language Specification(新规范)
    • JSR203-More New I/O APIs for the Java Platform(新规范)
    • JSR292与InvokeDynamic
    • 支持JDBC4.1规范
    • Path接口、DirectoryStream、Files、WatchService
    • jcmd
    • fork/join framework
    • Java Mission Control

    1、suppress异常(新语法)

    /**
     * 记录异常,不被淹没
     * addSuppressed
     */
    class ReadFile {
        public void read(String filename) throws BaseException {
            FileInputStream input = null;
            IOException readException = null;
            try {
                input = new FileInputStream(filename);
            } catch (IOException ex) {
                readException = ex;
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException ex) {
                        if (readException == null) {
                            readException = ex;
                        }else{
                            //使用java7的
                            readException.addSuppressed(ex);
                        }
                    }
                }
                if (readException != null) {
                    throw new BaseException(readException);
                }
            }
        }
    }
    

    2、捕获多个异常(新语法)

    public void handle() {
            ExceptionThrower thrower = new ExceptionThrower();
            try {
                thrower.manyExceptions();
            } catch (ExceptionA | ExceptionB ab) {
                System.out.println(ab.getClass());
            } catch (ExceptionC c) {
            }
        }
    

    3、try-with-resources(新语法)

    /**
     * try-with-resource
     * 不需要使用finally来保证打开的流被正确关闭
     * 这是自动完成的。
     * @created 2014-07-21
     */
    public class ResourceBasicUsage {
        public String readFile(String path) throws IOException {
            try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
                StringBuilder builder = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                    builder.append(String.format("%n"));
                }
                return builder.toString();
            }
        }
    }
    

    实现AutoCloseable

    /**
     * @created 2014-07-21
     */
    public class CustomResource  implements AutoCloseable {
        public void close() throws Exception {
            System.out.println("进行资源释放。");
        }
        public void useCustomResource() throws Exception {
            try (CustomResource resource = new CustomResource())  {
                System.out.println("使用资源。");
            }
        }
        public static void main(String[] args) {
            try {
                new CustomResource().useCustomResource();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    

    4、JSR341-Expression Language Specification(新规范)

    public static void main(String[] args){
            ELProcessor el = new ELProcessor();
            assert (el.eval("Math.random()") instanceof Double);
        }
    

    5、JSR203-More New I/O APIs for the Java Platform(新规范)

    • bytebuffer
    public class ByteBufferUsage {
        public void useByteBuffer() {
            ByteBuffer buffer = ByteBuffer.allocate(32);
            buffer.put((byte)1);
            buffer.put(new byte[3]);
            buffer.putChar('A');
            buffer.putFloat(0.0f);
            buffer.putLong(10, 100L);
            System.out.println(buffer.getChar(4));
            System.out.println(buffer.remaining());
        }
        public void byteOrder() {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            buffer.putInt(1);
            buffer.order(ByteOrder.LITTLE_ENDIAN);
            buffer.getInt(0); //值为16777216
        }
        public void compact() {
            ByteBuffer buffer = ByteBuffer.allocate(32);
            buffer.put(new byte[16]);
            buffer.flip();
            buffer.getInt();
            buffer.compact();
            int pos = buffer.position();
        }
        public void viewBuffer() {
            ByteBuffer buffer = ByteBuffer.allocate(32);
            buffer.putInt(1);
            IntBuffer intBuffer = buffer.asIntBuffer();
            intBuffer.put(2);
            int value = buffer.getInt(); //值为2
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            ByteBufferUsage bbu = new ByteBufferUsage();
            bbu.useByteBuffer();
            bbu.byteOrder();
            bbu.compact();
            bbu.viewBuffer();
        }
    }
    
    • filechannel
    public class FileChannelUsage {
        public void openAndWrite() throws IOException {
            FileChannel channel = FileChannel.open(Paths.get("my.txt"), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
            ByteBuffer buffer = ByteBuffer.allocate(64);
            buffer.putChar('A').flip();
            channel.write(buffer);
        }
        public void readWriteAbsolute() throws IOException {
            FileChannel channel = FileChannel.open(Paths.get("absolute.txt"), StandardOpenOption.READ, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
            ByteBuffer writeBuffer = ByteBuffer.allocate(4).putChar('A').putChar('B');
            writeBuffer.flip();
            channel.write(writeBuffer, 1024);
            ByteBuffer readBuffer = ByteBuffer.allocate(2);
            channel.read(readBuffer, 1026);
            readBuffer.flip();
            char result = readBuffer.getChar(); //值为'B'
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws IOException {
            FileChannelUsage fcu = new FileChannelUsage();
            fcu.openAndWrite();
            fcu.readWriteAbsolute();
        }
    }
    

    6、JSR292与InvokeDynamic

    JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform,支持在JVM上运行动态类型语言。在字节码层面支持了InvokeDynamic。

    • 方法句柄MethodHandle
    public class ThreadPoolManager {
        private final ScheduledExecutorService stpe = Executors
                .newScheduledThreadPool(2);
        private final BlockingQueue<WorkUnit<String>> lbq;
        public ThreadPoolManager(BlockingQueue<WorkUnit<String>> lbq_) {
            lbq = lbq_;
        }
        public ScheduledFuture<?> run(QueueReaderTask msgReader) {
            msgReader.setQueue(lbq);
            return stpe.scheduleAtFixedRate(msgReader, 10, 10, TimeUnit.MILLISECONDS);
        }
        private void cancel(final ScheduledFuture<?> hndl) {
            stpe.schedule(new Runnable() {
                public void run() {
                    hndl.cancel(true);
                }
            }, 10, TimeUnit.MILLISECONDS);
        }
        /**
         * 使用传统的反射api
         */
        public Method makeReflective() {
            Method meth = null;
            try {
                Class<?>[] argTypes = new Class[]{ScheduledFuture.class};
                meth = ThreadPoolManager.class.getDeclaredMethod("cancel", argTypes);
                meth.setAccessible(true);
            } catch (IllegalArgumentException | NoSuchMethodException
                    | SecurityException e) {
                e.printStackTrace();
            }
            return meth;
        }
        /**
         * 使用代理类
         * @return
         */
        public CancelProxy makeProxy() {
            return new CancelProxy();
        }
        /**
         * 使用Java7的新api,MethodHandle
         * invoke virtual 动态绑定后调用 obj.xxx
         * invoke special 静态绑定后调用 super.xxx
         * @return
         */
        public MethodHandle makeMh() {
            MethodHandle mh;
            MethodType desc = MethodType.methodType(void.class, ScheduledFuture.class);
            try {
                mh = MethodHandles.lookup().findVirtual(ThreadPoolManager.class,
                        "cancel", desc);
            } catch (NoSuchMethodException | IllegalAccessException e) {
                throw (AssertionError) new AssertionError().initCause(e);
            }
            return mh;
        }
        public static class CancelProxy {
            private CancelProxy() {
            }
            public void invoke(ThreadPoolManager mae_, ScheduledFuture<?> hndl_) {
                mae_.cancel(hndl_);
            }
        }
    }
    
    • 调用
    public class ThreadPoolMain {
        /**
         * 如果被继承,还能在静态上下文寻找正确的class
         */
        private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
        private ThreadPoolManager manager;
        public static void main(String[] args) {
            ThreadPoolMain main = new ThreadPoolMain();
            main.run();
        }
        private void cancelUsingReflection(ScheduledFuture<?> hndl) {
            Method meth = manager.makeReflective();
            try {
                System.out.println("With Reflection");
                meth.invoke(hndl);
            } catch (IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        private void cancelUsingProxy(ScheduledFuture<?> hndl) {
            CancelProxy proxy = manager.makeProxy();
            System.out.println("With Proxy");
            proxy.invoke(manager, hndl);
        }
        private void cancelUsingMH(ScheduledFuture<?> hndl) {
            MethodHandle mh = manager.makeMh();
            try {
                System.out.println("With Method Handle");
                mh.invokeExact(manager, hndl);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
        private void run() {
            BlockingQueue<WorkUnit<String>> lbq = new LinkedBlockingQueue<>();
            manager = new ThreadPoolManager(lbq);
            final QueueReaderTask msgReader = new QueueReaderTask(100) {
                @Override
                public void doAction(String msg_) {
                    if (msg_ != null)
                        System.out.println("Msg recvd: " + msg_);
                }
            };
            ScheduledFuture<?> hndl = manager.run(msgReader);
            cancelUsingMH(hndl);
            // cancelUsingProxy(hndl);
            // cancelUsingReflection(hndl);
        }
    }
    

    7、支持JDBC4.1规范

    • abort方法
    public class AbortConnection {
        public void abortConnection() throws SQLException {
            Connection connection = DriverManager
                    .getConnection("jdbc:derby://localhost/java7book");
            ThreadPoolExecutor executor = new DebugExecutorService(2, 10, 60,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
            connection.abort(executor);
            executor.shutdown();
            try {
                executor.awaitTermination(5, TimeUnit.MINUTES);
                System.out.println(executor.getCompletedTaskCount());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        private static class DebugExecutorService extends ThreadPoolExecutor {
            public DebugExecutorService(int corePoolSize, int maximumPoolSize,
                    long keepAliveTime, TimeUnit unit,
                    BlockingQueue<Runnable> workQueue) {
                super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
            }
            public void beforeExecute(Thread t, Runnable r) {
                System.out.println("清理任务:" + r.getClass());
                super.beforeExecute(t, r);
            }
        }
        public static void main(String[] args) {
            AbortConnection ca = new AbortConnection();
            try {
                ca.abortConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 自动关闭
    public class SetSchema {
        public void setSchema() throws SQLException {
            try (Connection connection = DriverManager
                    .getConnection("jdbc:derby://localhost/java7book")) {
                connection.setSchema("DEMO_SCHEMA");
                try (Statement stmt = connection.createStatement();
                        ResultSet rs = stmt.executeQuery("SELECT * FROM author")) {
                    while (rs.next()) {
                        System.out.println(rs.getString("name"));
                    }
                }
            }
        }
        public static void main(String[] args) {
            SetSchema ss = new SetSchema();
            try {
                ss.setSchema();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 自动映射
    public class UseSQLData {
    
        public void useSQLData() throws SQLException {
            try (Connection connection = DriverManager
                    .getConnection("jdbc:derby://localhost/java7book")) {
                Map<String,Class<?>> typeMap = new HashMap<String,Class<?>>();
                typeMap.put("java7book.Book", Book.class);
                try (Statement stmt = connection.createStatement();
                        ResultSet rs = stmt.executeQuery("SELECT * FROM book")) {
                    while (rs.next()) {
                        System.out.println(rs.getObject(1, Book.class));
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            UseSQLData usd = new UseSQLData();
            try {
                usd.useSQLData();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    8、Path接口(重要接口更新)

    public class PathUsage {
        public void usePath() {
            Path path1 = Paths.get("folder1", "sub1");
            Path path2 = Paths.get("folder2", "sub2");
            path1.resolve(path2); //folder1\sub1\folder2\sub2
            path1.resolveSibling(path2); //folder1\folder2\sub2
            path1.relativize(path2); //..\..\folder2\sub2
            path1.subpath(0, 1); //folder1
            path1.startsWith(path2); //false
            path1.endsWith(path2); //false
            Paths.get("folder1/./../folder2/my.text").normalize(); //folder2\my.text
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            PathUsage usage = new PathUsage();
            usage.usePath();
        }
    }
    

    9、DirectoryStream

    public class ListFile {
        public void listFiles() throws IOException {
            Path path = Paths.get("");
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.*")) {
                for (Path entry: stream) {
                    //使用entry
                    System.out.println(entry);
                }
            }
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws IOException {
            ListFile listFile = new ListFile();
            listFile.listFiles();
        }
    }
    

    10、Files

    public class FilesUtils {
        public void manipulateFiles() throws IOException {
            Path newFile = Files.createFile(Paths.get("new.txt").toAbsolutePath());
            List<String> content = new ArrayList<String>();
            content.add("Hello");
            content.add("World");
            Files.write(newFile, content, Charset.forName("UTF-8"));
            Files.size(newFile);
            byte[] bytes = Files.readAllBytes(newFile);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            Files.copy(newFile, output);
            Files.delete(newFile);
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws IOException {
            FilesUtils fu = new FilesUtils();
            fu.manipulateFiles();
        }
    }
    

    11、WatchService

    public class WatchAndCalculate {
        public void calculate() throws IOException, InterruptedException {
            WatchService service = FileSystems.getDefault().newWatchService();
            Path path = Paths.get("").toAbsolutePath();
            path.register(service, StandardWatchEventKinds.ENTRY_CREATE);
            while (true) {
                WatchKey key = service.take();
                for (WatchEvent<?> event : key.pollEvents()) {
                    Path createdPath = (Path) event.context();
                    createdPath = path.resolve(createdPath);
                    long size = Files.size(createdPath);
                    System.out.println(createdPath + " ==> " + size);
                }
                key.reset();
            }
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws Throwable {
            WatchAndCalculate wc = new WatchAndCalculate();
            wc.calculate();
        }
    }
    

    12、jcmd utility

    jcmd是为了替代jps出现了,包含了jps的大部分功能并新增了一些新的功能。

    • jcmd -l

    列出所有的Java虚拟机,针对每一个虚拟机可以使用help列出它们支持的命令。

    jcmd -l
    15308 org.eclipse.jetty.xml.XmlConfiguration /tmp/start4070493346048555702.properties /opt/educat/apps/conf/jetty8.xml
    5624 sun.tools.jcmd.JCmd -l
    20967 org.apache.flume.node.Application --no-reload-conf -f /opt/educat/flume_agent/conf/flume.conf -n log_agent
    
    • jcmd pid help
    jcmd 15308 help
    15308:
    The following commands are available:
    VM.commercial_features
    ManagementAgent.stop
    ManagementAgent.start_local
    ManagementAgent.start
    Thread.print
    GC.class_histogram
    GC.heap_dump
    GC.run_finalization
    GC.run
    VM.uptime
    VM.flags
    VM.system_properties
    VM.command_line
    VM.version
    help
    For more information about a specific command use 'help <command>'.
    
    • jcmd pid VM.flags查看启动参数
    jcmd 15308 VM.flags
    15308:
    -XX:+DisableExplicitGC 
    -XX:ErrorFile=/var/codecraft/logs/catapp.vmerr.log.201505071655 
    -XX:+HeapDumpOnOutOfMemoryError 
    -XX:HeapDumpPath=/var/codecraft/logs/catapp.heaperr.log.201505071655 -XX:InitialHeapSize=5368709120 
    -XX:+ManagementServer 
    -XX:MaxGCPauseMillis=100 
    -XX:MaxHeapSize=5368709120 
    -XX:MaxPermSize=268435456 
    -XX:+PrintAdaptiveSizePolicy 
    -XX:+PrintCommandLineFlags 
    -XX:+PrintGC 
    -XX:+PrintGCApplicationStoppedTime 
    -XX:+PrintGCDateStamps 
    -XX:+PrintGCDetails 
    -XX:+PrintGCTimeStamps 
    -XX:+PrintHeapAtGC 
    -XX:+PrintTenuringDistribution 
    -XX:StringTableSize=49999 
    -XX:+UnlockExperimentalVMOptions 
    -XX:+UseCompressedOops 
    -XX:+UseG1GC
    
    • jcmd pid GC.heap_dump D:d.dump 导出堆信息
    • jcmd pid GC.class_histogram查看系统中类的统计信息
    • jcmd pid VM.system_properties查看系统属性内容
    • jcmd pid Thread.print 打印线程栈
    • jcmd pid VM.uptime 查看虚拟机启动时间
    • jcmd pid PerfCounter.print 查看性能统计
    jcmd 15308 PerfCounter.print
    15308:
    java.ci.totalTime=79326405
    java.cls.loadedClasses=19977
    java.cls.sharedLoadedClasses=0
    java.cls.sharedUnloadedClasses=0
    java.cls.unloadedClasses=1443
    java.property.java.class.path="/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-xml-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/servlet-api-3.0.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-http-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-continuation-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-server-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-security-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-servlet-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-webapp-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-deploy-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/lib/jetty-servlets-8.1.9.v20130131.jar:/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131/l"
    java.property.java.endorsed.dirs="/usr/local/jdk1.7.0_21/jre/lib/endorsed"
    java.property.java.ext.dirs="/usr/local/jdk1.7.0_21/jre/lib/ext:/usr/java/packages/lib/ext"
    java.property.java.home="/usr/local/jdk1.7.0_21/jre"
    java.property.java.library.path="/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib"
    java.property.java.version="1.7.0_21"
    java.property.java.vm.info="mixed mode"
    java.property.java.vm.name="Java HotSpot(TM) 64-Bit Server VM"
    java.property.java.vm.specification.name="Java Virtual Machine Specification"
    java.property.java.vm.specification.vendor="Oracle Corporation"
    java.property.java.vm.specification.version="1.7"
    java.property.java.vm.vendor="Oracle Corporation"
    java.property.java.vm.version="23.21-b01"
    java.rt.vmArgs="-javaagent:/opt/educat/apps/lib/jolokia-jvm-1.1.0-agent.jar=port=23061 -Xloggc:/var/codecraft/logs/catapp.gc.log.201505071655 -XX:ErrorFile=/var/codecraft/logs/catapp.vmerr.log.201505071655 -XX:HeapDumpPath=/var/codecraft/logs/catapp.heaperr.log.201505071655 -Xmx5g -Xms5g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintCommandLineFlags -XX:+PrintAdaptiveSizePolicy -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:StringTableSize=49999 -Djetty.home=/opt/educat/apps/server/jetty-distribution-8.1.9.v20130131 -Dapp.port=8061 -Dmedis_environment=online -Dcore.step=app -DSTOP.PORT=38061 -Djetty.port=8061 -Dcom.sun.management.jmxremote.authenticate=false -Dapp.logdir=/var/codecraft/logs -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -Dapp.ip=10.64.28.207 -Dapp.cont"
    java.rt.vmFlags=""
    java.threads.daemon=72
    java.threads.live=128
    java.threads.livePeak=129
    java.threads.started=1444
    sun.ci.compilerThread.0.compiles=2595
    sun.ci.compilerThread.0.method=""
    sun.ci.compilerThread.0.time=1290
    sun.ci.compilerThread.0.type=1
    sun.ci.compilerThread.1.compiles=2802
    sun.ci.compilerThread.1.method=""
    sun.ci.compilerThread.1.time=1413
    sun.ci.compilerThread.1.type=2
    sun.ci.lastFailedMethod=""
    sun.ci.lastFailedType=0
    sun.ci.lastInvalidatedMethod=""
    sun.ci.lastInvalidatedType=0
    sun.ci.lastMethod="org/codehaus/groovy/classgen/VariableScopeVisitor checkVariableNameForDeclaration"
    sun.ci.lastSize=2184
    sun.ci.lastType=1
    sun.ci.nmethodCodeSize=12188576
    sun.ci.nmethodSize=24492688
    sun.ci.osrBytes=196694
    sun.ci.osrCompiles=156
    sun.ci.osrTime=8521713
    sun.ci.standardBytes=2072839
    sun.ci.standardCompiles=5241
    sun.ci.standardTime=70804692
    sun.ci.threads=2
    sun.ci.totalBailouts=0
    sun.ci.totalCompiles=5397
    sun.ci.totalInvalidates=0
    sun.classloader.findClassTime=358334873
    sun.classloader.findClasses=507
    sun.classloader.parentDelegationTime=30062667
    sun.cls.appClassBytes=63743816
    sun.cls.appClassLoadCount=58098
    sun.cls.appClassLoadTime=9843833
    sun.cls.appClassLoadTime.self=5288490
    sun.cls.classInitTime=2617049
    sun.cls.classInitTime.self=1088905
    sun.cls.classLinkedTime=4605704
    sun.cls.classLinkedTime.self=541928
    sun.cls.classVerifyTime=4055324
    sun.cls.classVerifyTime.self=2423448
    sun.cls.defineAppClassTime=3206202
    sun.cls.defineAppClassTime.self=386302
    sun.cls.defineAppClasses=16465
    sun.cls.initializedClasses=14546
    sun.cls.isUnsyncloadClassSet=0
    sun.cls.jniDefineClassNoLockCalls=94
    sun.cls.jvmDefineClassNoLockCalls=4405
    sun.cls.jvmFindLoadedClassNoLockCalls=32671
    sun.cls.linkedClasses=16465
    sun.cls.loadInstanceClassFailRate=0
    sun.cls.loadedBytes=43314456
    sun.cls.lookupSysClassTime=87247
    sun.cls.methodBytes=34262690
    sun.cls.nonSystemLoaderLockContentionRate=133
    sun.cls.parseClassTime=3099390
    sun.cls.parseClassTime.self=2670584
    sun.cls.sharedClassLoadTime=9647
    sun.cls.sharedLoadedBytes=0
    sun.cls.sharedUnloadedBytes=0
    sun.cls.sysClassBytes=12986737
    sun.cls.sysClassLoadTime=503885
    sun.cls.systemLoaderLockContentionRate=0
    sun.cls.time=15382336
    sun.cls.unloadedBytes=5087120
    sun.cls.unsafeDefineClassCalls=1555
    sun.cls.verifiedClasses=16383
    sun.gc.cause="No GC"
    sun.gc.collector.0.invocations=85
    sun.gc.collector.0.lastEntryTime=24164511065
    sun.gc.collector.0.lastExitTime=24164628388
    sun.gc.collector.0.name="G1 incremental collections"
    sun.gc.collector.0.time=7628099
    sun.gc.collector.1.invocations=1
    sun.gc.collector.1.lastEntryTime=24543200515
    sun.gc.collector.1.lastExitTime=24544107869
    sun.gc.collector.1.name="G1 stop-the-world full collections"
    sun.gc.collector.1.time=907355
    sun.gc.generation.0.agetable.bytes.00=0
    sun.gc.generation.0.agetable.bytes.01=4294976
    sun.gc.generation.0.agetable.bytes.02=2014880
    sun.gc.generation.0.agetable.bytes.03=5406352
    sun.gc.generation.0.agetable.bytes.04=4875176
    sun.gc.generation.0.agetable.bytes.05=2865952
    sun.gc.generation.0.agetable.bytes.06=4374048
    sun.gc.generation.0.agetable.bytes.07=2058664
    sun.gc.generation.0.agetable.bytes.08=3574376
    sun.gc.generation.0.agetable.bytes.09=6923448
    sun.gc.generation.0.agetable.bytes.10=1541088
    sun.gc.generation.0.agetable.bytes.11=1347376
    sun.gc.generation.0.agetable.bytes.12=735888
    sun.gc.generation.0.agetable.bytes.13=402632
    sun.gc.generation.0.agetable.bytes.14=713272
    sun.gc.generation.0.agetable.bytes.15=728688
    sun.gc.generation.0.agetable.size=16
    sun.gc.generation.0.capacity=4510973976
    sun.gc.generation.0.maxCapacity=5368709144
    sun.gc.generation.0.minCapacity=24
    sun.gc.generation.0.name="young"
    sun.gc.generation.0.space.0.capacity=4510973960
    sun.gc.generation.0.space.0.initCapacity=1128267784
    sun.gc.generation.0.space.0.maxCapacity=5368709128
    sun.gc.generation.0.space.0.name="eden"
    sun.gc.generation.0.space.0.used=580911104
    sun.gc.generation.0.space.1.capacity=8
    sun.gc.generation.0.space.1.initCapacity=8
    sun.gc.generation.0.space.1.maxCapacity=8
    sun.gc.generation.0.space.1.name="s0"
    sun.gc.generation.0.space.1.used=0
    sun.gc.generation.0.space.2.capacity=8
    sun.gc.generation.0.space.2.initCapacity=8
    sun.gc.generation.0.space.2.maxCapacity=5368709128
    sun.gc.generation.0.space.2.name="s1"
    sun.gc.generation.0.space.2.used=0
    sun.gc.generation.0.spaces=3
    sun.gc.generation.1.capacity=857735176
    sun.gc.generation.1.maxCapacity=5368709128
    sun.gc.generation.1.minCapacity=8
    sun.gc.generation.1.name="old"
    sun.gc.generation.1.space.0.capacity=857735176
    sun.gc.generation.1.space.0.initCapacity=4240441352
    sun.gc.generation.1.space.0.maxCapacity=5368709128
    sun.gc.generation.1.space.0.name="space"
    sun.gc.generation.1.space.0.used=155730608
    sun.gc.generation.1.spaces=1
    sun.gc.generation.2.capacity=138412032
    sun.gc.generation.2.maxCapacity=268435456
    sun.gc.generation.2.minCapacity=20971520
    sun.gc.generation.2.name="perm"
    sun.gc.generation.2.space.0.capacity=138412032
    sun.gc.generation.2.space.0.initCapacity=20971520
    sun.gc.generation.2.space.0.maxCapacity=268435456
    sun.gc.generation.2.space.0.name="perm"
    sun.gc.generation.2.space.0.used=138212560
    sun.gc.generation.2.spaces=1
    sun.gc.lastCause="Heap Inspection Initiated GC"
    sun.gc.policy.collectors=1
    sun.gc.policy.desiredSurvivorSize=264241152
    sun.gc.policy.generations=3
    sun.gc.policy.maxTenuringThreshold=15
    sun.gc.policy.name="GarbageFirst"
    sun.gc.policy.tenuringThreshold=15
    sun.gc.tlab.alloc=0
    sun.gc.tlab.allocThreads=0
    sun.gc.tlab.fastWaste=0
    sun.gc.tlab.fills=0
    sun.gc.tlab.gcWaste=0
    sun.gc.tlab.maxFastWaste=0
    sun.gc.tlab.maxFills=0
    sun.gc.tlab.maxGcWaste=0
    sun.gc.tlab.maxSlowAlloc=0
    sun.gc.tlab.maxSlowWaste=0
    sun.gc.tlab.slowAlloc=0
    sun.gc.tlab.slowWaste=0
    sun.management.JMXConnectorServer.0.authenticate="false"
    sun.management.JMXConnectorServer.0.remoteAddress="service:jmx:rmi:///jndi/rmi://edu-cat02.lf.codecraft.com:8199/jmxrmi"
    sun.management.JMXConnectorServer.0.ssl="false"
    sun.management.JMXConnectorServer.0.sslNeedClientAuth="false"
    sun.management.JMXConnectorServer.0.sslRegistry="false"
    sun.management.JMXConnectorServer.address="service:jmx:rmi://127.0.0.1/stub/rO0ABXNyAC5qYXZheC5tYW5hZ2VtZW50LnJlbW90ZS5ybWkuUk1JU2VydmVySW1wbF9TdHViAAAAAAAAAAICAAB4cgAaamF2YS5ybWkuc2VydmVyLlJlbW90ZVN0dWLp/tzJi+FlGgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc3AAtVbmljYXN0UmVmMgAADDEwLjY0LjI4LjIwNwAAhbjWmVwaDwiNg3l3YeUAAAFNLZX68oACAHg="
    sun.os.hrt.frequency=1000000
    sun.os.hrt.ticks=24580753795
    sun.perfdata.majorVersion=2
    sun.perfdata.minorVersion=0
    sun.perfdata.overflow=0
    sun.perfdata.size=32768
    sun.perfdata.timestamp=259316
    sun.perfdata.used=17792
    sun.property.sun.boot.class.path="/usr/local/jdk1.7.0_21/jre/lib/resources.jar:/usr/local/jdk1.7.0_21/jre/lib/rt.jar:/usr/local/jdk1.7.0_21/jre/lib/sunrsasign.jar:/usr/local/jdk1.7.0_21/jre/lib/jsse.jar:/usr/local/jdk1.7.0_21/jre/lib/jce.jar:/usr/local/jdk1.7.0_21/jre/lib/charsets.jar:/usr/local/jdk1.7.0_21/jre/lib/jfr.jar:/usr/local/jdk1.7.0_21/jre/classes"
    sun.property.sun.boot.library.path="/usr/local/jdk1.7.0_21/jre/lib/amd64"
    sun.rt._sync_ContendedLockAttempts=297851
    sun.rt._sync_Deflations=438863
    sun.rt._sync_EmptyNotifications=0
    sun.rt._sync_FailedSpins=0
    sun.rt._sync_FutileWakeups=349651
    sun.rt._sync_Inflations=438971
    sun.rt._sync_MonExtant=16256
    sun.rt._sync_MonInCirculation=0
    sun.rt._sync_MonScavenged=0
    sun.rt._sync_Notifications=1580811
    sun.rt._sync_Parks=1935145
    sun.rt._sync_PrivateA=0
    sun.rt._sync_PrivateB=0
    sun.rt._sync_SlowEnter=0
    sun.rt._sync_SlowExit=0
    sun.rt._sync_SlowNotify=0
    sun.rt._sync_SlowNotifyAll=0
    sun.rt._sync_SuccessfulSpins=0
    sun.rt.applicationTime=24559855809
    sun.rt.createVmBeginTime=1430988913170
    sun.rt.createVmEndTime=1430988913429
    sun.rt.internalVersion="Java HotSpot(TM) 64-Bit Server VM (23.21-b01) for linux-amd64 JRE (1.7.0_21-b11), built on Apr  4 2013 04:03:29 by "java_re" with gcc 4.3.0 20080428 (Red Hat 4.3.0-8)"
    sun.rt.interruptedBeforeIO=0
    sun.rt.interruptedDuringIO=0
    sun.rt.javaCommand="org.eclipse.jetty.xml.XmlConfiguration /tmp/start4070493346048555702.properties /opt/educat/apps/conf/jetty8.xml"
    sun.rt.jvmCapabilities="1000000000000000000000000000000000000000000000000000000000000000"
    sun.rt.jvmVersion=387252225
    sun.rt.safepointSyncTime=2333795
    sun.rt.safepointTime=15955181
    sun.rt.safepoints=18365
    sun.rt.threadInterruptSignaled=0
    sun.rt.vmInitDoneTime=1430988913232
    sun.threads.vmOperationTime=9516621
    sun.urlClassLoader.readClassBytesTime=958824201
    sun.zip.zipFile.openTime=72163038
    sun.zip.zipFiles=3838
    

    13、fork/join

    Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

    14、Java Mission Control

    在JDK7u40里头提供了Java Mission Control,这个是从JRockit虚拟机里头迁移过来的类似JVisualVm的东东。

    15、其他

    • Binary Literals支持
    • Numeric Literals的下划线支持
    • Strings in switch Statements

    参考

    文章太长了,此平台不支持了,另开一篇文章:Java8到Java12新特性见这里 https://www.jianshu.com/p/e5fba5376371

    相关文章

      网友评论

        本文标题:从Java5到Java12每个版本的新特性(1)

        本文链接:https://www.haomeiwen.com/subject/ehcjcqtx.html