Java 7 的更改,特性和增强

Java 7 的更改,特性和增强

原文: https://howtodoinjava.com/java7/java-7-changes-features-and-enhancements/

我已经介绍了许多 java 7 更改,这些更改在发行版中是新的。 在这篇文章中,我将对它们进行总结,以便有兴趣的人可以在短时间内快速了解所有特性。

Features covered in this post

Improved type Inference Or Diamond Operator
Automatic resource management with try-with-resources
NIO 2.0
Exception handling improvements
    Suppressed exceptions
    Catch Multiple Exceptions in catch block
Number formatting enhancement
String class support in switch statement
Binary Literals with prefix "0b"
ForkJoin Framework
Automatic reloading with WatchService
G1 Garbage Collector

改进的类型推断

在 Java 7 之前,使用泛型时,必须为变量类型及其实际类型提供类型参数。 现在,此新的 Java 7 特性已使它有所缓解,并且声明右侧的空白菱形将可以正常工作。

编译器在 Java 7 中足够聪明,可以识别出空白菱形推断出在声明左侧定义的类型。

public class ElvisOperatorTest {
    public static void main(String[] args) {
        @SuppressWarnings("unused")
        Map params = new HashMap<>();
    }
}

使用try-with-resources的自动资源管理

在 Java 7 之前,我们必须使用finally块来清理资源。 finally块不是强制性的,但是清理资源是为了防止系统损坏。 使用 Java 7,无需显式的资源清理。 它是自动完成的。 在try-with-resources块(try(…){…})中初始化资源时,将完成自动资源清除。

由于新接口AutoCloseable而进行清理。 try块完成后,JVM 将立即调用其 close方法。 您不应在代码中调用close()方法。 这应该自动称为 JVM。 手动调用它可能会导致意外结果。

public class ResourceManagementInJava7
{
    public static void main(String[] args)
    {
        try (BufferedReader br = new BufferedReader(new FileReader("C:/temp/test.txt")))
        {
            String sCurrentLine;
            while ((sCurrentLine = br.readLine()) != null)
            {
                System.out.println(sCurrentLine);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

NIO 2.0

Java SE 7 引入了java.nio.file包及其相关包java.nio.file.attribute,为文件 I/O 和访问默认文件系统提供了全面的支持。 路径类是一个很大的补充,它允许您以统一的方式表示操作系统中的任何路径。 新的 API 是对旧 API 的补充,并提供了一些有用的方法检查,删除,复制和移动文件。 您也可以像在 Linux 中那样创建符号链接和硬链接。 JDK 7 新文件 API 还能够使用通配符/正则表达式搜索文件。 您还将获得支持以查看目录中的更改。

继续探索链接网页中的所有这些更改。

异常处理方面的改进

Java 7 在异常处理方面也带来了一些不错的增强。 这些可以大致分为两个特性:

受抑制的异常

顾名思义,抑制的异常是在代码中引发的异常,但是以某种方式被忽略。 如果您还记得try-catch-finally块的执行顺序以及它们如何返回任何值或异常,则您会记得,在try块中也抛出异常的情况下,抑制了finally块中引发的异常。 在 Java 7 之前的版本中,通过记录日志了解了这些异常(如果已实现),但是一旦finally块结束,您就无法控制这些异常类型。 使用 Java 7 中的新特性,您还可以控制这些受抑制的异常。

用法示例如下:

public class SuppressedExceptionDemoWithTryFinallyNew
{
    /**
    * Executable member function demonstrating suppressed exceptions
    * Suppressed expression is added back in primary exception
    */
    public static void memberFunction() throws Exception
    {
        Throwable th = null;
        DirtyResource resource= new DirtyResource();
        try
        {
              resource.accessResource();
        }
        catch(Exception e)
        {
            th = e;
            throw e;
        }
        finally
        {
            try
            {
                resource.close();
            }
            catch(Exception e)
            {
                if(th != null)
                {
                    e.addSuppressed(th); //Add to primary exception
                    throw e;
                }
            }
        }
    }
   /**
    * Executable function demonstrating suppressed exceptions.
    */
   public static void main(String[] arguments) throws Exception
   {
      try
      {
          memberFunction();
      }
      catch(Exception ex)
      {
          err.println("Exception encountered: " + ex.toString());
          final Throwable[] suppressedExceptions = ex.getSuppressed();
          final int numSuppressed = suppressedExceptions.length;
          if (numSuppressed > 0)
          {
              err.println("tThere are " + numSuppressed + " suppressed exceptions:");
              for (final Throwable exception : suppressedExceptions)
              {
                  err.println("tt" + exception.toString());
              }
          }
      }
   }
}

Output:

Exception encountered: java.lang.NullPointerException: Remember me. I am your worst nightmare !! I am Null pointer exception !!
    There are 1 suppressed exceptions:
        java.lang.RuntimeException: I wanted to access this resource. Bad luck. Its dirty resource !!!

阅读有关链接文章的更多信息。

catch块中捕获多个异常

在此特性中,现在您可以在单个catch块中捕获多个异常。 在 Java 7 之前,您只能捕获一个。 要指定期望的异常列表,请使用竖线(|)。

让我们来看一个例子。

try
{
       //Do some processing which throws NullPointerException; I am sending directly
       throw new NullPointerException();
}

//You can catch multiple exception added after 'pipe' character
catch(NullPointerException | IndexOutOfBoundsException ex)
{
       throw ex;
}

请记住:如果catch块处理多个异常类型,则catch参数隐式为final。 在此示例中,catch参数ex是最终的,因此您不能在catch块中为其分配任何值。

数字格式增强特性

如果必须读取数字“1000000”,那么在第一个站点中读取该数字有多方便。 不多吧? 我们习惯于以10,00,000格式读取数字。 好消息是 Java 已经开始支持以这种格式写数字。 好吧,不完全是这样,而是匹配的格式。

现在,您可以像上面这样写上面的数字:10_00_000。 足够好了,不是吗?

/**
 * Supported in int
 * */
int improvedInt = 10_00_000;
/**
 * Supported in float
 * */
float improvedFloat = 10_00_000f;
/**
 * Supported in long
 * */
float improvedLong = 10_00_000l;
/**
 * Supported in double
 * */
float improvedDouble = 10_00_000;

switch语句中的字符串类支持

如果您还记得 java 7 之前的switch语句,则它仅支持intenum类型。 现在,随着 Java 7 的发布,还添加了对String类的支持。 让我们来看一个例子。

switch (token)
{
	case ("one"):
		return "Token one identified";

	case ("two"):
		return "Token one identified";

	case ("three"):
		return "Token one identified";

	case ("four"):
		return "Token one identified";

	default:
		return "No token was identified";
}

前缀为0b的二进制字面值

在 JDK 7 中,您可以为整数类型(字节,短型,整型和长型)以前缀0b(或0B)以二进制形式表示字面值。 在 JDK 7 之前,您只能使用八进制值(前缀为0)或十六进制值(前缀为0x0X)。 例如:

int sameVarOne = 0b01010000101;

or if use the number formatting feature as well.

int sameVarTwo = 0B01_010_000_101;

ForkJoin 框架

在 Java 程序中有效使用并行内核一直是一个挑战。 很少有本地框架可以将工作分配到多个核心,然后将它们加入以返回结果集。 Java 7 已将此特性作为 Fork 和 Join 框架合并。

基本上,Fork-Join 将手头的任务分解为多个小任务,直到该小任务足够简单,可以将其解决而无需进一步拆分。 这就像分而治之的算法。 在此框架中要注意的一个重要概念是,理想情况下,没有工作线程处于空闲状态。 他们实现了一种工作窃取算法,即闲置的工作器从忙碌的工作器那里窃取了工作。

它基于 Java 并发性思想领袖 Doug Lea 的工作。 Fork/Join 处理线程的麻烦; 您只需要向框架指出可以分解并递归处理的部分。 它采用伪代码(摘自 Doug Lea 关于该主题的论文):

Result solve(Problem problem) {
	if (problem is small)
		directly solve problem
	else {
		split problem into independent parts
		fork new subtasks to solve each part
		join all subtasks
		compose result from subresults
	}
}

使用WatchService自动重新加载

每个应用程序都有一些配置,预期配置文件中的每次更改都会刷新该配置。 解决该问题的过去方法包括拥有一个线程,该线程根据配置文件的“最新更新时间戳”定期轮询文件更改。

现在使用 Java 7,情况已经改变。 Java 7 引入了一项出色的特性:WatchServiceWatchService是 JDK 的内部服务,监视注册对象的更改。 这些注册的对象必定是Watchable接口的实例。 向WatchService注册Watchable实例时,我们需要指定我们感兴趣的更改事件的类型。

链接的文章中提供了WatchService的示例用法。

G1 垃圾收集器

JDK 7 引入了一个称为 G1 的新垃圾收集器,它是垃圾的缩写形式。 G1 垃圾收集器在垃圾最多的地方执行清理。 为此,它将 Java 堆内存划分为多个区域,而不是 Java 7 版本之前的 3 个区域(新旧空间)。 G1 完全可以预测,并且可以为内存密集型应用程序提供更高的吞吐量。

这就是此快速摘要的全部内容。 您可以在此链接中找到特性的完整列表。

学习愉快!