Java SE 5.0 - SE 8 的功能增强
Table of Contents
前言
在学习 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 程序员都需要学习的一个问题,也是容易忽视的一个问题。
简单的提一下,各个装箱类都有这样形式的两个静态方法: valueOf
和 parseXXX
, 合理使用这两个方法可以减少装箱拆箱的次数。
比如: 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
二进制整数字面量,也就是说可以用类似 0b1110
或 0B1110
的形式来设置整数值,但是好像是默认为 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.AutoCloseable
和 java.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 的功能增强的更多相关文章
- java分为 三类 ME,SE,EE
java分为 三类 ME,SE,EE Java SE=Java Standard EditionJava EE=Java Enterprise Edition Java ME=Java Mobile ...
- Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币
什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...
- 在Android中访问内置SE和基于SE的卡模拟(一)
2013-10-10 编写 前言 在“十问Android NFC手机上的卡模拟”文中仅仅简单的介绍了一下相关的概念,如果需要了解基于SE的卡模拟的更多细节,也就是,究竟在Android的NFC手机上, ...
- Java基础-输入输出-3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc。
3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc. try { FileInputStream in = ...
- 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 ...
- JAVA基础-输入输出:1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上。
1.编写TextRw.java的Java应用程序,程序完成的功能是:首先向TextRw.txt中写入自己的学号和姓名,读取TextRw.txt中信息并将其显示在屏幕上. package Test03; ...
- SpringBoot2.0小程序支付功能实现weixin-java-pay
SpringBoot2.0小程序支付功能实现weixin-java-pay WxJava - 微信开发 Java SDK(开发工具包); 支持包括微信支付.开放平台.公众号.企业微信/企业号.小程序等 ...
- Android Studio 3.0 下载 使用新功能介绍
谷歌2017发布会更新了挺多内容的,而且也发布了AndroidStudio3.0预览版,一些功能先睹为快.(英语一般,有些翻译不太好) 下载地址 https://developer.android.g ...
- Java 开发 2.0: 现实世界中的 Redis
原文地址:http://www.ibm.com/developerworks/cn/java/j-javadev2-22/ 之前,我已在本系列中讨论过 NoSQL 的概念,也介绍了一些与 Java 平 ...
随机推荐
- Jenkins使用分组过滤分类
背景:Jenkins项目过多,通过选项卡的方式过滤需要的项目 1.点击选择卡上的加号 2.填写要分组的名字 3.可选择某个job进行分类,或者使用正则表达式的方式进行分类,楼主是根据正则进行匹配, 4 ...
- 【CF660E】Different Subsets For All Tuples(组合数学)
点此看题面 大致题意: 有一个长度为\(n\)的数列,每个位置上数字的值在\([1,m]\)范围内,则共有\(m^n\)种可能的数列.分别求出每个数列中本质不同的子序列个数,然后求和. 一些分析 首先 ...
- 砍树,POJ(2665)
题目链接:http://poj.org/problem?id=2665 解题报告: 这里的区域没有重复,若有重复的话,模拟即可. #include <cstdio> #include &l ...
- windows/Linux主机重启NetBackup服务和后台进程
关闭并启动所有NetBackup服务和后台进程 要关闭并启动所有NetBackup服务和后台驻留程序,请从命令行输入以下命令: 在Windows上: 要关闭所有NetBackup服务: install ...
- CentOS安装配置MongoDB
1.下载安装包: wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.3.tgz 2.解压: tar -zxvf mongodb-l ...
- 今天 小小收获, 看了 sam Xiao 的好帖子 明白了 泛型委托 的 意思。
Func<int,int,int> cAdd1 = (int x, int y) => { return x + y; }; int result= aAdd1(1,2); cons ...
- kmeans聚类中的坑 基于R shiny 可交互的展示
龙君蛋君 2015年5月24日 1.背景介绍 最近公司在用R 建模,老板要求用shiny 展示结果,建模的过程中用到诸如kmean聚类,时间序列分析等方法.由于之前看过一篇讨论kmenas聚类针对某一 ...
- js 实现链表
我们通常会在c++这类语言中学习到链表的概念,但是在js中由于我们可以动态的扩充数组,加之有丰富的原生api.我们通常并不需要实现链表结构.由于突发奇想,我打算用js实现一下: 首先我们要创建链表: ...
- javascript中call,apply,bind的使用
不同点: 1.call():传参方式跟bind一样(都是以逗号隔开的传参方式),但是跟apply(以数组的形式传参)不一样, 2.bind(): 此方法应用后的情形跟call和apply不一样.该方法 ...
- CBCGPImage的GetSize的问题及解决方法
BCGControlBar Pro for MFC 25.10是目前(2018-07-16)网上能够找到的最新能够使用的版本,我配合Visual Studio 2010使用.在单文档MFC程序的视图中 ...