Table of Contents

  1. 前言
  2. Java 5.0
    1. Generics
    2. Enhanced for Loop
    3. Autoboxing
    4. Typesafe Enums
    5. Varargs
    6. Static Import
    7. Annotations
  3. Java SE 6
  4. Java SE 7
    1. Binary Literals
    2. Underscores in Numeric Literals
    3. Strings in switch Statements
    4. Type Inference for Generic Instance Creation
    5. The try-with-resources Statement
    6. Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
  5. Java SE 8
    1. Lambda Expressions
    2. Improved Type Inference
    3. Annotations on Java Types
    4. Repeating Annotations
    5. Method Parameter Reflection
  6. 结语

前言

在学习 Python 的过程中就因为不同版本之间的不同而迷惑过,现在在学习 Java 的过程中我也遇见了类似的问题。

市面上的 Java 教材使用的 Java 版本各不相同,各个版本之间的语言特性来回切换,让人有点不知所措。

这篇博客参考 Java Programming Language Enhancements 整理了一下 Java 5.0 - 8 的功能增强,希望对有相同困惑的你有所帮助。

Java 5.0

就目前的情况来说,无论是市面上的 Java 书籍还是实际使用的 Java 版本,大多是 >= 5.0 的,因此,这一节就只简单介绍一下 5.0 的功能增强。

Generics

熟悉 Java 语言的同学对 泛型 这个特性应该并不陌生,这是一个很常用的特性,单独把这个特性拎出来讲都可以写好几篇博客了。

这里就不过多的谈论和泛型相关的内容了,简单举个使用的例子就结束:

List<String> list = new ArrayList<String>();

Enhanced for Loop

for-each 循环是在 5.0 才可以开始使用的,凡是实现了 Iterable 接口的对象或 数组 都可以使用这一循环方式:

for (Type item : Iterable or array) {
...
}

但是不得不说,这样的语法形式是真的丑,据说是为了保留 System.in 而没有将 in 作为新的循环关键字。

Autoboxing

自动装箱这一特性可谓是给编写 Java 代码的程序员带来了极大的便利,但也带来了一下其他的问题,比如:

  • 频繁的装箱拆箱操作带来的性能损失

这可以说是每个 Java 程序员都需要学习的一个问题,也是容易忽视的一个问题。

简单的提一下,各个装箱类都有这样形式的两个静态方法: valueOfparseXXX, 合理使用这两个方法可以减少装箱拆箱的次数。

比如: Integer.valueOf 返回的是 Integer, 而 Integer.parseInt 返回的是 int.

Typesafe Enums

在 Java 5.0 以前是没有枚举类型的,要使用枚举只有像这样:

public static final int SEASON_WINTER = 0;
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;

这样做会带来一些问题,因此,从 Java 5.0 开始就支持枚举类型了:

enum Season { WINTER, SPRING, SUMMER, FALL }

这里有一个很有趣的问题,虽然从 Java 5.0 开始就引入了标准的枚举类型,但是在 Android SDK 的源码中,依然还是在使用 final int 型常量的形式。

有兴趣的话可以看看这篇文章了解为什么这么做的原因:Android Performance: Avoid using ENUM on Android – AndroidPub

Varargs

Java 居然是在 5.0 才引入可变参数这一特性的,5.0 以前的 Java 程序员格式化字符串的时候岂不是很辛苦 @_@

public static int sum(int... nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
return sum;
}

和大多数语言一样,虽然说是可变参数,但实际上就是一个数组。

Static Import

静态导入用的好绝得是一大神器,虽然说现代 IDE 的自动补全功能已经很强大,但是,能够少写一些代码还是很好的:

import static java.lang.Math.*;

double r = cos(PI * theta);

当然了,使用的时候还是应该注意避免污染命名空间。

Annotations

注解机制的重要性我想要个不需要我说了,现代的各种 Java 框架,基本上都离不开这一机制的使用。

就算不使用这一机制实现什么功能,编写 Java 代码的使用诸如 @Override 的注解还是少不了的。

注解一时爽,一直注解一直爽!

Java SE 6

No language changes were introduced in Java SE 6.

Java SE 7

我看过的教程还没有哪本用的是 Java 7, 可怜的孩子 @_@

Binary Literals

二进制整数字面量,也就是说可以用类似 0b11100B1110 的形式来设置整数值,但是好像是默认为 int 型。

// An 8-bit 'byte' value:
byte aByte = (byte)0b00100001; // A 16-bit 'short' value:
short aShort = (short)0b1010000101000101; // Some 32-bit 'int' values:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case. // A 64-bit 'long' value. Note the "L" suffix:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

Underscores in Numeric Literals

数字字面量中间可以有下划线 _ 了,在写长整数的使用利用这一特性可以很方便的分清楚现在有几个 0.

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

Strings in switch Statements

switch 语句的 case 选项中可以使用字符串了,由于看的第一个教材是 Java 5.0 版的,搞得我现在都还不怎么习惯这一特性。

Type Inference for Generic Instance Creation

类型推断绝对是一个很方便的功能,因为这意味着像下面这样的代码:

Map<String, List<String>> myMap = new HashMap<String, List<String>>();

可以写成这样:

Map<String, List<String>> myMap = new HashMap<>();

Nice!!!

The try-with-resources Statement

可以说,凡是和 I/O 操作相关的对象,在最后都需要调用 close() 方法,这是一个很繁琐的操作,但不操作还不得行!

现在,我们可以这样,让 Java 自动帮你调用 close() 方法:

static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}

凡是实现了 java.lang.AutoCloseablejava.io.Closeable 接口的对象,都可以使用这种方式。

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

这里我们主要关注 Catching Multiple Exception Types 这一特性。

在编写 Java 代码的过程中,很有可能会遇到需要捕获多个异常但是对这些异常都差不多的情况:

try {
...
} catch (Exception e) {
e.printStackTrace();
}

有多少个异常就写多少个 catch 块时很繁琐的,因此,从 Java 7 开始,就可以这样:

catch (IOException | SQLException ex) {
throw ex;
}

通过 | 操作符同时捕获多个类型的异常,很棒,不是吗?

Java SE 8

Java 8 是具有里程碑意义的一个版本,现在我们常用的 Java 版本就是这个版本,成熟的特性,丰富的类库。

Lambda Expressions

作为函数式编程和 Lisp 的爱好者,看到 Java 支持 Lambda 表达式的时候心情是激动的,在看到 Java 中 Lambda 的使用后,就更激动了。

除了 Lambda 表达式以外,还新增了方法引用、接口默认方法、Stream 库等新功能。

可以说是打造了一个相对完善的函数式编程环境。

当然了,Java 本身还是一个 OOP 的语言,但是,能够有地方使用 Lambda 表达式就很爽了。

Improved Type Inference

Java 8 增强了类型推断的功能,具体是什么样的就不多做讨论了,反正,直接用就可以了。

Annotations on Java Types

Java 8 以前的注解貌似只能用在类和方法上,但是现在可以在 任何地方 使用:

@NonNull String str;

这一点对于一些工具来说是很有用的,比如一些 Json 解析库。

Repeating Annotations

现在可以在一个地方多出使用相同的注解,就像这样:

@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }

Method Parameter Reflection

反射可以获取方法的参数了,在反射面前一个类已经没有多少隐私可言了 @_@

还记的前一段时间看到的一个新闻,说以前一些 Android 开发者可以通过反射和 JNI 的方式调用 SDK 中的隐藏接口,搞得 Google 只能将那些接口变成反射不出来。

NB!!!

结语

其实直接用 Java 8 的话可以不用管那个特性是那个版本开始支持的,直接用就可以了。

但是,感觉了解一下相关的内容会有助于 Java 的学习,于是便简单的操作了一下。

博客中提到的一些特性只是简单的提了一下它们的名字,而没有说它们具体是怎么样的,如果要了解的话,可以 Google。

还省略了一些内容,有兴趣的可以去看一下官方文档: Java Programming Language Enhancements.

Java SE 5.0 - SE 8 的功能增强的更多相关文章

  1. java分为 三类 ME,SE,EE

    java分为 三类  ME,SE,EE Java SE=Java Standard EditionJava EE=Java Enterprise Edition Java ME=Java Mobile ...

  2. Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币

    什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...

  3. 在Android中访问内置SE和基于SE的卡模拟(一)

    2013-10-10 编写 前言 在“十问Android NFC手机上的卡模拟”文中仅仅简单的介绍了一下相关的概念,如果需要了解基于SE的卡模拟的更多细节,也就是,究竟在Android的NFC手机上, ...

  4. Java基础-输入输出-3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc。

    3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc. try { FileInputStream in = ...

  5. Java基础-输入输出-2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt

    2.编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt ...

  6. JAVA基础-输入输出:1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上。

    1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上. package Test03; ...

  7. SpringBoot2.0小程序支付功能实现weixin-java-pay

    SpringBoot2.0小程序支付功能实现weixin-java-pay WxJava - 微信开发 Java SDK(开发工具包); 支持包括微信支付.开放平台.公众号.企业微信/企业号.小程序等 ...

  8. Android Studio 3.0 下载 使用新功能介绍

    谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快.(英语一般,有些翻译不太好) 下载地址 https://developer.android.g ...

  9. Java 开发 2.0: 现实世界中的 Redis

    原文地址:http://www.ibm.com/developerworks/cn/java/j-javadev2-22/ 之前,我已在本系列中讨论过 NoSQL 的概念,也介绍了一些与 Java 平 ...

随机推荐

  1. Jenkins使用分组过滤分类

    背景:Jenkins项目过多,通过选项卡的方式过滤需要的项目 1.点击选择卡上的加号 2.填写要分组的名字 3.可选择某个job进行分类,或者使用正则表达式的方式进行分类,楼主是根据正则进行匹配, 4 ...

  2. 【CF660E】Different Subsets For All Tuples(组合数学)

    点此看题面 大致题意: 有一个长度为\(n\)的数列,每个位置上数字的值在\([1,m]\)范围内,则共有\(m^n\)种可能的数列.分别求出每个数列中本质不同的子序列个数,然后求和. 一些分析 首先 ...

  3. 砍树,POJ(2665)

    题目链接:http://poj.org/problem?id=2665 解题报告: 这里的区域没有重复,若有重复的话,模拟即可. #include <cstdio> #include &l ...

  4. windows/Linux主机重启NetBackup服务和后台进程

    关闭并启动所有NetBackup服务和后台进程 要关闭并启动所有NetBackup服务和后台驻留程序,请从命令行输入以下命令: 在Windows上: 要关闭所有NetBackup服务: install ...

  5. CentOS安装配置MongoDB

    1.下载安装包: wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.3.tgz 2.解压: tar -zxvf mongodb-l ...

  6. 今天 小小收获, 看了 sam Xiao 的好帖子 明白了 泛型委托 的 意思。

    Func<int,int,int> cAdd1 = (int x, int y) => { return x + y; }; int result= aAdd1(1,2); cons ...

  7. kmeans聚类中的坑 基于R shiny 可交互的展示

    龙君蛋君 2015年5月24日 1.背景介绍 最近公司在用R 建模,老板要求用shiny 展示结果,建模的过程中用到诸如kmean聚类,时间序列分析等方法.由于之前看过一篇讨论kmenas聚类针对某一 ...

  8. js 实现链表

    我们通常会在c++这类语言中学习到链表的概念,但是在js中由于我们可以动态的扩充数组,加之有丰富的原生api.我们通常并不需要实现链表结构.由于突发奇想,我打算用js实现一下: 首先我们要创建链表: ...

  9. javascript中call,apply,bind的使用

    不同点: 1.call():传参方式跟bind一样(都是以逗号隔开的传参方式),但是跟apply(以数组的形式传参)不一样, 2.bind(): 此方法应用后的情形跟call和apply不一样.该方法 ...

  10. CBCGPImage的GetSize的问题及解决方法

    BCGControlBar Pro for MFC 25.10是目前(2018-07-16)网上能够找到的最新能够使用的版本,我配合Visual Studio 2010使用.在单文档MFC程序的视图中 ...