Tag: java

  1. 优雅的在Java应用关闭时清理资源

    本文基于JDK 1.8.0_45 在实际的Java应用中经常会遇到一些类是需要打开资源,如果资源类在使用完毕时可以使用try-with-resources清理关闭资源,但是如果该资源的生命周期是与应用生命周期相同的时候我们该如何在应用关闭时清理关闭资源呢? 在Java中可以使用Runtime注册一个关闭时的钩子,在这个钩子里的代码就会在应用关闭的时候执行,如下所示: Runtime.getRuntime().addShutdownHook(new Thread(() -> { // do something }, "cleanup-thread")); 这种方式注册的线程是一个只初始化了但是没有启动的线程,当JVM开始关闭流程时所有注册的shutdown hook都会被启动并并发执行,在都执行完毕后悔进行可能的退出时的资源清理,然后完全关闭。 另外请注意: 当关闭流程开始之后只有halt方法可以强制关闭JVM; 当关闭流程开始之后禁止注册新的shutdown hook或者去除已注册的shutdown hook; 小心死锁; 建议不要执行太长时间,这是因为一方面用户在关停应用时不会期望等待太长时间,另一方面可能操作系统不会允许太长时间的关停; 如果JVM由于一些特殊的原因终止,比如kill -9,JVM不会保证shutdown hook的执行; 如果在注册了一个shutdown hook之后在一些情况下需要将之删除,可以通过以下代码: Thread shutdownHook = new Thread(() -> { // do…

    on JDK8 java shutdownhook 优雅关闭

  2. try-with-resources

    本文基于JDK 1.8.0_45 在JDK7中提供了一个新的特性:try-with-resources,该特性大大的降低了资源操作时的资源关闭相关的代码,原来的写法如下所示: InputStream stream = new FileInputStream("file.txt"); try { // do something } finally { stream.close(); } 当资源实现了AutoCloseable接口时,新写法如下所示: try (InputStream stream = new FileInputStream("file.txt")) { // do something } 在代码块执行完毕之后会自动调用resource的close方法关闭资源,再也不需要因为忘记关闭资源而导致资源泄露之类的问题了。 在实现该接口时有以下几点最佳实践: 建议在实现的时候抛出具体的异常,如果肯定没有异常发生则不要抛出异常; 如果关闭失败建议放弃继续尝试关闭底层的资源,而只是将其标志为关闭并抛出异常; 建议不要抛出InterruptedException异常以避免潜在的问题; 建议实现为幂等的,以避免多次调用出现问题;…

    on resource java JDK8 try-with-resources

  3. Java中的比较器

    本文基于JDK 1.8.0_45 在Java中我们经常需要对数据进行排序,比如Collections.sort(list)或者Arrays.sort(array)。对于Java中的基本数据类型可以很简单的使用<,>,来进行比较,比如 int[] array = new int[]{2, 5, 3}; Arrays.sort(array); for (int i : array) { System.out.print(i + ", ");// 2, 3, 5, } 但是对于对象而言使用只是进行比较对象的内存地址是否一样,如果重写了equals方法则可以使用自定义的规则进行判断两个对象是否一样。 Object o1 = new Object(); Object o2 = new Object(); System.out.println(…

    on java JDK8 Java8 函数式编程 functional programming 比较器 Comparator Comparable

  4. Java中的枚举

    本文基于JDK 1.8.0_45 一个简单的枚举例子 public enum EnumExample { enum1, enum2; } 以上是一个简单的枚举例子,我们通过关键字enum定义了一个名叫EnumExample的枚举类,在其中我们定义了两个枚举类型:enum1和enum2。 在Java中所有的枚举类默认都会继承自Enum抽象类,所有的枚举类型都会自动包含Enum抽象类中定义的方法。其中包含了获取枚举类型的名字、顺序、所属的类,另外还有通过枚举类和名字获取枚举类型的静态方法,如下所示: public enum EnumExample { enum1, enum2; public static class Test { public static void main(String[] args) { System.out.println(enum1.name());// enum1 System.out.println(enum1.ordinal());// 0 System.…

    on java enum 枚举 EnumSet EnumMap 动态添加枚举

  5. Java中的注解

    本文基于JDK 1.8.0_45 一个简单的注解的例子 @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.CONSTRUCTOR, ElementType.METHOD}) public @interface MyAnnotation { String value(); } 以上是一个简单的注解的例子,从中可以看到: 通过@interface标识这个类是一个注解; 通过在注解类上加上注解来标识这个注解的元信息; 注解可以通过定义一些方法来给注解添加更多的信息; 所有的注解类型都会自动的继承自Annotation接口。该接口主要是提供给Class来使用,比如反射等。 请注意显式的实现Annotation接口并不会定义一个注解类型,该接口也不会定义一种注解类型。 该接口提供了基本的equals、hashCode、toString和annotationType方法,其中annotationType会返回相应注解实际上的class。 内置注解-Documented 变量 无 用法 只能用于其他注解上; 该注解用于标识它需要被JavaDoc之类的工具处理,并被包括在生成的文档中; 例子 package com.oomlife.java.example; import java.…

    on java annotation 注解 Repeatable