java基础(1)-比较jdk5,jdk6,jdk7的新特性

jdk8已经出来好长时间了,这里自己学习时简单总结的jdk5,jdk6和jdk7的新特性:
本文提纲:

一.jdk5的新特性

二.jdk6的新特性

三.jdk7的新特性

一.jdk5的新特性

首先简单介绍一下各种特性及其使用

1.泛型(Generic)
C++通过模板技术可以指定集合的元素类型,而Java在1.5之前一直没有相对应的功能。一个集合可以放任何类型的对象,

相应地从集合里面拿对象的时候我们也不得不对他们进行强制得类型转换。猛虎引入了泛型,它允许指定集

Collection<String> c = new ArrayList();
c.add(new Date());
  编译器会给出一个错误:
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date) 

A、类型安全

抛弃List、Map,使用List<T>、Map<K,V>给它们添加元素或者使用Iterator<T>遍历时,编译期就可以给你检查出类型错误

B、方法参数和返回值加上了Type

抛弃List、Map,使用List<T>、Map<K,V>

C、不需要类型转换

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

String str=list.get(i);

D、类型通配符“?”

假设一个打印List<T>中元素的方法printList,我们希望任何类型T的List<T>都可以被打印:

代码:

public void printList(List<?> list,PrintStream out)throws IOException{
for(Iterator<?> i=list.iterator();i.hasNext();){
System.out.println(i.next.toString());
  }
}

如果通配符?让我们的参数类型过于广泛,我们可以把List<?>、Iterator<?> 修改为

List<? Extends Number>、Iterator<? Extends Number>限制一下它。

2.For-Each循环
For-Each循环得加入简化了集合的遍历。假设我们要遍历一个集合对其中的元素进行一些处理。典型的代码为:

 void processAll(Collection c){
 for(Iterator i=c.iterator(); i.hasNext();){
 MyClass myObject = (MyClass)i.next();
    myObject.process();
}
}
#使用For-Each循环,我们可以把代码改写成:
void processAll(Collection<MyClass> c){
for (MyClass myObject :c)
    myObject.process();
 } 

这段代码要比上面清晰许多,并且避免了强制类型转换。

3.自动装包/拆包(Autoboxing/unboxing)
自动装包/拆包大大方便了基本类型数据和它们包装类地使用。
自动装包:基本类型自动转为包装类.(int >> Integer)
自动拆包:包装类自动转为基本类型.(Integer >> int)
在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀,现在自动转换机制解决了我们的问题。

4.枚举(Enums)
JDK1.5加入了一个全新类型的“类”-枚举类型。为此JDK1.5引入了一个新关键字enmu,我们可以这样来定义一个枚举类型。

public enum Color{
Red,
White,
Blue
}
#然后可以这样来使用Color myColor = Color.Red.
#枚举类型还提供了两个有用的静态方法values()和valueOf(). 我们可以很方便地使用它们,例如
for (Color c : Color.values())
System.out.println(c); 

5.可变参数(Varargs)
可变参数使程序员可以声明一个接受可变数目参数的方法。注意,可变参数必须是函数声明中的最后一个参数。

假设我们要写一个简单的方法打印一些对象,

在JDK1.5之前,我们可以用重载来实现,但是这样就需要写很多的重载函数,显得不是很有效。

如果使用可变参数的话我们只需要一个函数就行了.

public void write(Object... objs) {
 for (Object obj: objs)
 System.out.println(obj);
 } 

在引入可变参数以后,Java的 反射包也更加方便使用了。对于c.getMethod

("test", new Object[0]).invoke(c.newInstance(), new Object[0])),

现在我们可以这样写了c.getMethod("test").invoke(c.newInstance()),这样的代码比 原来清楚了很多。

6.静态导入(Static Imports)
要使用用静态成员(方法和变量)我们必须给出提供这个方法的类。使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,

使用这些静态成员无需再给出他们的类名。

import static java.lang.Math.*;
……. 

 r = sin(PI * 2); //无需再写r = Math.sin(Math.PI);

但是,过度使用这个特性也会一定程度上降低代码地可读性。

6.Annotations 它是java中的metadata

A.Tiger中预定义的三种标准annotation

(1).Override 方法重载

指出某个method覆盖了superclass 的method当你要覆盖的方法名拼写错时编译不通过

(2).Deprecated 方法过时

指出某个method或element类型的使用是被阻止的,子类将不能覆盖该方法

(3).SupressWarnings 编译器警告

关闭class、method、field、variable 初始化的编译期警告,比如:List没有使用 Generic,则@SuppressWarnings("unchecked")去掉编译期警告。

B.自定义annotation

public @interface Marked{}

C.meta-annotation

或者说annotation的annotation

四种标准的meta-annotation全部定义在java.lang.annotaion包中:
Target
指定所定义的annotation可以用在哪些程序单元上
如果Target没有指定,则表示该annotation可以使用在任意程序单元上
代码

@Target({ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.LOCAL_VARIABLE,
        ElementType.METHOD,
        ElementType.PACKAGE,
        ElementType.PARAMETER,
        ElementType.TYPE})
  public @interface TODO {}  

Annotation的反射
我们发现java.lang.Class有许多与Annotation的反射相关的方法,如getAnnotations、isAnnotationpresent
我们可以利用Annotation反射来做许多事情,比如自定义Annotation来做Model对象验证
代码

 @Retention(RetentionPolicy.RUNTIME)
 @Target({ ElementType.FIELD, ElementType.METHOD })
 public @interface RejectEmpty {
    /** hint title used in error message */
    String value() default "";
 }    

 @Retention(RetentionPolicy.RUNTIME)
 @Target( { ElementType.FIELD, ElementType.METHOD })
 public @interface AcceptInt {
     int min() default Integer.MIN_VALUE;
     int max() default Integer.MAX_VALUE;
     String hint() default "";
  }  

使用@RejectEmpty和@AcceptInt标注我们的Model的field,然后利用反射来做Model验证

7.新的格式化方法(java.util.Formatter)

formatter.format("Remaining account balance: $%.2f", balance);

8.新的线程模型和并发库Thread Framework
HashMap的替代者ConcurrentHashMap和ArrayList的替代者CopyOnWriteArrayList
在大并发量读取时采用java.util.concurrent包里的一些类会让大家满意BlockingQueue、Callable、Executor、Semaphore...

二.jdk6的新特性

1.引入了一个支持脚本引擎的新框架

2.UI的增强

3.对WebService支持的增强(JAX-WS2.0和JAXB2.0)

4.一系列新的安全相关的增强

5.JDBC4.0

6.Compiler API

7.通用的Annotations支持

三.jdk7的新特性

1.二进制字面量
JDK7开始,终于可以用二进制来表示整数(byte,short,int和long)。使用二进制字面量的好处是,可以是
代码更容易被理解。语法非常简单,只要在二进制数值前面加0b或者0B

byte nByte = (byte)0b0001;
short nShort = (short)0B0010;
int nInt = 0b0011;
long nLong = 0b0100L;

2.数字字面量可以出现下划线

对于一些比较大的数字,我们定义起来总是不方面,经常缺少或者增加位数。JDK7为我们提供了一种解决
方案,下划线可以出现在数字字面量。

int a = 10_0000_0000;
long b = 0xffff_ffff_ffff_ffffl;
byte c = 0b0001_1000;

注意:你只能将下划线置于数字之间,以下使用方法是错误的,
(1).数字的开头或者结尾

(2).小数点的前后

(3).‘F’或者‘f’的后缀

(4).只能用数字的位置

int err1 = _11,err2=11_;
float err3=3._4,err4=3_.4;
long err5=0x888_f;

3.switch 语句可以用字符串了

private static void switchString(String str){
switch(str){
case "one":
System.err.println("1");
break;
case "two":
System.out.println("2");
break;
default :
System.out.println("err");
}
}

4.泛型实例的创建可以通过类型推断来简化

以后你创建一个泛型实例,不需要再详细说明类型,只需用<>,编译器会自动帮你匹配

#例如

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

#可以简化为
Map<String, List<String>> myMap = new HashMap<>();

5.在可变参数方法中传递非具体化参数(Non-Reifiable Formal Parameters),改进编译警告和错误
有些参数类型,例如ArrayList<Number> 和List<String>,是非具体化的(non-reifiable).在编译阶段,
编译器会擦除该类型信息。
Heap pollution 指一个变量被指向另外一个不是相同类型的变量。例如

List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrown

回到我们的主题,在jdk7中,当你定义下面的函数时

public static <T> void addToList (List<T> listArg, T... elements) {
for (T x : elements) {
listArg.add(x);
}
}

你会得到一个warning

warning: [varargs] Possible heap pollution from parameterized vararg type

在jdk7之前,当你调用一个含有非具体化参数的可变参数方法,你必须自行保证不会发生“heap
pollution”。这有一个问题,如果调用者对方法不熟悉,他根本无法判断。JDK7对此做了改进,在该方法被定
义时久发出警告

1.加 annotation @SafeVarargs
2.加 annotation @SuppressWarnings({"unchecked", "varargs"})
3.使用编译器参数 –Xlint:varargs;

6.try-with-resources 语句
jdk7提供了try-with-resources,可以自动关闭相关的资源(只要该资源实现了AutoCloseable接口,jdk7为绝
大部分资源对象都实现了这个接口)

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

try 语句块中还可以同时处理多个资源,可以跟普通的try语句一样catch异常,有finally语句块

try (
java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
}catch(…){
}finally{
}

7.Catch多个Exception,rethrow exception 改进了类型检测

很多时候,我们捕获了多个异常,却做了相同的事情,比如记日志,包装成新的异常,然后rethrow。这
时,代码就不那么优雅了,例如

catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}

Jdk7允许捕获多个异常

catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}

注意,catch后面的异常参数是final的,不能重新再复制

当你重新抛出多个异常时,不再需要详细定义异常类型了,编译器已经知道你具体抛出的是哪个异常了。你
只需在方法定义的时候声明需要抛出的异常即可

public void call() throws ReflectiveOperationException, IOException {
try {
callWithReflection(arg);
} catch (final Exception e) {
logger.trace("Exception in reflection", e);
throw e;
}
}

8.JDBC4.1更新了两个新特性

1. Connection,ResultSet 和Statement 都实现了Closeable 接口,所有在try-with-resources 语句中调
用,就可以自动关闭相关资源了

try (Statement stmt = con.createStatement()){
…
}

2. RowSet 1.1:引入RowSetFactory接口和RowSetProvider类,可以创建JDBC driver支持的各种row sets

RowSetFactory myRowSetFactory = null;
JdbcRowSet jdbcRs = null;
ResultSet rs = null;
Statement stmt = null;
try {
myRowSetFactory = RowSetProvider.newFactory();//用缺省的RowSetFactory 实现
jdbcRs = myRowSetFactory.createJdbcRowSet();
//创建一个 JdbcRowSet 对象,配置数据库连接属性
jdbcRs.setUrl("jdbc:myDriver:myAttribute");
jdbcRs.setUsername(username);
jdbcRs.setPassword(password);
jdbcRs.setCommand("select ID from TEST");jdbcRs.execute();}

RowSetFactory 接口包括了创建不同类型的RowSet的方法
createCachedRowSet
createFilteredRowSet
createJdbcRowSet
createJoinRowSet
createWebRowSet

9.更新了NIO2.0文件系统

java.io.File 不够完美吧。Jdk7提供了一套新的文件系统,会让你满意的。
先来聊聊java.io.File的七宗罪吧:)
1.很多方法失败时候都没有抛出异常,很难查找原因
2.方法 rename 在不同平台中运行有问题
3.不能真正支持 symbolic links
4.不能读取文件的更详细属性,比如权限,所有者……
5.访问 文件的 metadata 效率低下
6.很多方法性能不行。例如处理比较大的目录
7.无法递归查找文件树,以及存在循环的symbolic links可能造成问题

主要包括:
FileSystem 提供了许多方法来获得当前文件系统的相关信息。
Path 处理路径(文件和目录),包括
创建path,Paths.get(String s)
获得path的详细信息 getName(),getXX()…
删除path的冗余信息 toRealPath
转换path toAbsolutePath()
合并两个path resolve()
在两个path之间创建相对路径 relativeze()
比较路径 equal() startsWith(),endWith()

Files 支持各种文件操作,包括
移动文件,
复制文件,
删除文件,
更详细的文件属性,包括文件权限,创建者,修改时间……
Walking the File Tree(递归遍历文件树)
Watch a Directory for Change (监听文件更改)

9.异步IO AIO

概述
JDK7引入了Asynchronous I/O。I/O编程中,常用到两种模式:Reactor 和Proactor。Reactor就
是Java的NIO。当有事件触发时,我们得到通知,进行相应的处理。Proactor就是我们今天要讲的AIO了。
AIO进行I/O操作,都是异步处理,当事件完成时,我们会得到通知。
JDK7的AIO包括网络和文件操作。两者大同小异,本文通过一个完整的客户端/服务器Sample来详细说
明aio的网络操作。
AIO提供了两种异步操作的监听机制。第一种通过返回一个Future对象来事件,调用其get()会等到操作
完成。第二种类似于回调函数。在进行异步操作时,传递一个CompletionHandler,当异步操作结束时,会调
用CompletionHandler.complete 接口

时间: 2024-10-29 03:17:09

java基础(1)-比较jdk5,jdk6,jdk7的新特性的相关文章

jdk7的新特性

在jdk7的新特性方面主要有下面几方面的增强: 1.jdk7语法上 1.1二进制变量的表示,支持将整数类型用二进制来表示,用0b开头. // 所有整数 int, short,long,byte都可以用二进制表示 // An 8-bit 'byte' value: byte aByte = (byte) 0b00100001; // A 16-bit 'short' value: short aShort = (short) 0b1010000101000101; // Some 32-bit '

Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码

美国时间 09 月 25 日,Oralce 正式发布了 Java 11,这是据 Java 8 以后支持的首个长期版本. 为什么说是长期版本,看下面的官方发布的支持路线图表. Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码可以看出 Java 8 扩展支持到 2025 年,而 Java 11 扩展支持到 2026 年. 现在大部分都在用 Java 8,Java 9 和 10 目前很少有人在用,至少我没有发现有公司在生产环境应用的,那就是找死. 现在 Java 11 长期支持,也已

Java 11正式发布,这几个逆天新特性教你写出更牛逼的代码

就在前段时间,Oracle 官方宣布 Java 11 (18.9 LTS) 正式发布,可在生产环境中使用! 这无疑对我们来说是一大好的消息.作为一名java开发者来说,虽然又要去学习和了解java11,但内心还是欣慰的.我想至少你和我一样的心情:Java在手,天下我有! 今天我们来看一下Java 11到底是什么.他有什么特别的.到底要不要升级到Java 11. Java 11有什么特别的 在Oracle官网中,进入下载页面,第一个可供下载的JDK版本已经提换成了Java SE 11 (LTS),

类的加载、时机、反射、模板设计、jdk7/jdk8新特性(二十六)

1.类的加载概述和加载时机 * A:类的加载概述 * 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. * 加载 * 就是指将class文件读入内存,并为之创建一个Class对象.任何类被使用时系统都会建立一个Class对象. * 连接 * 验证 是否有正确的内部结构,并和其他类协调一致 * 准备 负责为类的静态成员分配内存,并设置默认初始化值 * 解析 将类的二进制数据中的符号引用替换为直接引用 * 初始化 就是我们以前讲过的初始化

36套精品Java高级课,架构课,java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,第三方支付,web安全,高并发,高性能,高可用,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,大型分布式电商项目实战视频教程

新年伊始,学习要趁早,点滴记录,学习就是进步! QQ:1225462853 视频课程包含: 36套Java精品高级课架构课包含:java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,架构设计,web安全,高并发,高性能,高可用,高可扩展,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,工作流,程序调优,负载均衡,Solr集群与应用,主从复制,中间件,全文检索,Spring boot,Spring cloud,Dubbo,Elasticsearch,Redis,ActiveMQ

JDK7的新特性——switch语句可以用字符串语句

1 //jdk7.0中switch可以使用字符串做条件 2 public class TestSwitch02 { 3 public static void main(String[] args){ 4 String a = "向良峰"; 5 6 switch(a){//JDK 7的新特性,表达式可以是字符串! 7 case "哔哩哔哩": 8 System.out.println("输入的是哔哩哔哩"); 9 break; 10 case &q

java基础笔记(6)----面向对象的三大特性

简介:面向对象的三大特性就是封装,继承,多态,是面向对象的核心. 封装 简介:封装是类的边界,可以对数据起到保护作用 特性:属性私有,提供公开的get/set方法 属性私有:private 数据类型 变量名:---->private修饰的属性只能在本类使用 公开的get/set方法 public修饰---- >在任何类中都可以使用 get方法:----获取属性的值 public 数据类型 getXxx(){ return this.属性名 } set方法:----修改属性的值 public v

JDK5.0以后的新特性

泛型.静态导入.可变参数.增强for()循环.自动拆装箱 一.泛型 1.概述:将原来具体的类型参数化,将数据类型(只能是引用数据类型)作为一种参数传递,提高代码的安全性: 2.格式:<数据类型> 3.位置: 1)数组.集合在创建对象的时候 ArrayList<String> al = new ArrayList<String>(); //后面的String叫作泛型推断 ArrayList集合使用泛型<String>限定后则该集合就只能存储String类型的元

夯实Java基础系列目录

学习Java语言也有很长一段时间了,但是之前只是学习了Java的基础部分,对于什么IO流.多线程之类的只学习了一点,并没有过多的去学习,所以随着后面学习的深入,发现没有这部分知识更加的重要,所以现在我又重新来复习一遍Java基础,努力打好自己的Java基础,在这里我要说句话(其实一万句都不够):Java基础非常重要!Java基础非常重要!Java基础非常重要! 一.Java基础 1.夯实Java基础(一)--数组 2.夯实Java基础(二)--面向对象之封装 3.夯实Java基础(三)--面向对