参考链接: Java多捕获Multicatch

Java7语言,语法的变化

1、switch语句中的String

在Java6及之前,case语句中的常量只能是byte,char,short和int(也可以是对应的封装类型Byte,Character,Short和Integer)或枚举常量。Java7中增加了String

public static void main(String[] args) {

TestSwitchUseString("1");

TestSwitchUseString("2");

TestSwitchUseString("");

}

public static void TestSwitchUseString(String str){

switch (str) {

case "1":

System.out.println("It's Monday");

break;

case "2":

System.out.println("It's Tuesday");

break;

default:

System.out.println("It's Default");

break;

}

}

2、更强的数字文本表示法

二进制文本再也不用这样去转换 int x = Integer.parseInt("1100110",2);  在Java7中可以直接这样写: int x = 0b1100110;

可以用下划线(_)作数字的分隔符,为了阅读数字更容易,Java在编译时会去掉下划线。  如 long num = 3_456_231_890L;

3、改善后的异常处理

multicatch  这是在Java6及之前的处理方式:

public Configuration getConfig(String fileName) {

Configuration cfg = null;

try {

String fileText = getFile(fileName);

cfg = verifyConfig(parseConfig(fileText));

} catch (FileNotFoundException fnfx) {

System.err.println("Config file '" + fileName + "' is missing");

} catch (IOException e) {

System.err.println("Error while processing file '" + fileName + "'");

} catch (ConfigurationException e) {

System.err.println("Config file '" + fileName + "' is not consistent");

} catch (ParseException e) {

System.err.println("Config file '" + fileName + "' is malformed");

}

return cfg;

}

现在利用multicatch可以在一个catch中处理多个异常

public Configuration getConfig(String fileName) {

Configuration cfg = null;

try {

String fileText = getFile(fileName);

cfg = verifyConfig(parseConfig(fileText));

} catch (FileNotFoundException | ParseException | ConfigurationException e) {

System.err.println("Config file '" + fileName

+ "' is missing or malformed");

} catch (IOException iox) {

System.err.println("Error while processing file '" + fileName + "'");

}

return cfg;

}

final重抛

catch(final Exception e){... throw e}

关键字final 表明实际抛出的异常就是运行时遇到的异常,这样就不会抛出笼统的异常类型,从而避免在上层只能用笼统的catch捕获。

try-with-resources(TWR)  Java6及之前的资源要自己在finaly中关闭而在Java7中可以实现资源自动关闭 如:

try(OutputStream out = new FileOutputStream(file); InputStream is = url.openStream()){

byte[] buf = new byte[4096];

int len;

while((len= is.read(buf))>0){

out.write(buf,0,len);

}

}

这是资源自动化管理代码块的基本形式—-把资源放在try的圆括号内。要确保try-with-resources生效,正确的用法是为各个资源声明独立变量。因为嵌套声明的话,java编译器可能不能正确按顺序释放相关资源。目前TWR特性依靠一个新定义的接口实现AutoCloseable.TWR的try从句中出现的资源类必须实现这个接口,Java7平台的大多数资源类都被修改过,已经实现了AutoCloseable

4、钻石语法

针对创建泛型定义的实例太过繁琐的问题,Java7做了一项改进,以减少处理泛型时敲键盘的次数。如:

Map<Integer,Map<String,String>> usersLists = new HashMap<Integer,Map<String,String>>();

在Java7中编译器会推断出右侧的类型信息

Map<Integer,Map<String,String>> usersLists = new HashMap<>();

5、NIO.2

5.1、IO发展简史

Java1.4中引入NIO增加了以下特性:

为IO操作抽象出缓冲区和通道层 字符集的编码和解码能力 提供了能够映射为内存数据的接口 实现非阻塞IO的能力 基于流行Perl实现的正则表达式类库

NIO.2中的目标

一个能批量获取文件属性的文件系统接口,去掉和特定文件系统相关的API,还有一个用于标准文件系统实现的服务提供接口 提供一个套接字和文件都能够进行异步(与轮询,非阻塞相对)IO操作的API 完成通道功能,包括额外绑定,选项配置和多播数据报的支持。

5.2、Path

关键基础类

Path —>Path类中的方法可以用来获取路径信息,访问该路径中的各元素,将路径转换为其他形式,或提取路径中的一部分。有的方法还可以匹配路径字串以及移除路径中的冗余项Paths —>工具类,提供返回一个路径的辅助方法,比如get(String first,String…more)和get(URI uri)FileSystem —>与文件系统交互的类,无论是默认的文件系统,还是通过其统一资源标识(URI)获取的可选文件系统FileSystems —>工具类,提供各种方法,比如其中用于返回默认文件系统的FileSystems.getDefault();

Path不一定代表真实的文件或目录。你可以随心所欲地操作Path,用Filse中的功能来检查文件是否存在,并对它进行处理。Path并不仅限于文件系统,它也能表示zip或jar这样的文件系统。

//默认的获取Path实例方法

Path path = Paths.get("/testpath/webmonitor/webmonitor.zip");//  等同于  Path path = FileSystems.getDefault().getPath("/testpath/webmonitor/webmonitor.zip");

System.out.println("FileName:"+path.getFileName());

System.out.println("Number of Name element:"+path.getNameCount());//路径名字分段个数

System.out.println("Parent path:"+path.getParent() );

System.out.println("Root path:"+ path.getRoot());

System.out.println("SubPath from root:" + path.subpath(0, 1));

path.normalize();//去掉冗余的信息

System.out.println(path.toAbsolutePath());//获取绝对路径

try {

path.toRealPath();//这个是真实映射到实际物理硬盘上的路径

} catch (IOException e) {

e.printStackTrace();

}

//取得两个path之间的路径差

Path testPath = Paths.get("/testpath/webmonitor");

Path newPath = testPath.relativize(path);

System.out.println("newPath:"+newPath);

Path newPath2 = path.relativize(testPath);

System.out.println("newPath2:"+newPath2);

//合并path

Path path1 = Paths.get("/test/");

Path path2 = Paths.get("path2/file.name");//没加上“/”表示一个绝对路径

Path path3 = path1.resolve(path2);// 等同于 path1.resolve("path2/file.name");

System.out.println("path3:"+path3);

5.3、处理目录和目录树

新引入的java.nio.file.DirectoryStream 接口和它的实现类提供了很多功能:

循环遍历目录中的子项,比如查找目录中的文件;用glob表达式(如Foobar)进行目录子项匹配和基于MIME的内容检测(如text/xml文件);glob模式匹配类似于正则表达式,但稍有不同用walkFileTree方法实现递归移动,复制和删除操作

在目录中查找文件  //查找trunk工程中所有properties文件

Path dir = Paths.get("C:/Users/twang/Desktop/trunk");//设定一个路径

try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir,"*.properties")){//返回一个经过过滤的DirectoryStream,其中包含.properties文件

for(Path path:stream){

System.out.println(path.getFileName());

}

}catch(IOException e){

e.printStackTrace();

}

//以上代码是单个目录中处理,如果需要递归过滤多个目标则用到时目录树

遍历目录树  java7r提供了遍历目录树的功能,其中的关键方法是

Files.walkFileTree(Path startingDir,FileVisitor<? super Path> visitor)

实现FileVisitor接口比较麻烦,最少要实现下面5个方法(T 一般是path)

FileVisitResult preVisitDirectory(T dir)FileVisitResult preVisitDirectoryFailed(T dir,IOException exc)FileVisitResult visitFile(T file,BasicFileAttributes attrs)FileVisitResult visitFileFailed(T file,IOException exc)FileVisitResult postVisitDirectory(T dir,IOException exc)

Java7提供了一个默认的实现 SimpleFileVisitor

//打印出一个目录下所有的Java文件名

private static void getAllJavaFile() {

Path startDir = Paths.get("D:/tim/newWorkSpace");//设置起始目录

try {

Files.walkFileTree(startDir,new FindJavaVisitor());//调用 walkFileTree

} catch (IOException e) {

e.printStackTrace();

}

}

private static class FindJavaVisitor extends SimpleFileVisitor<Path>{//扩展于SimpleFileVisitor<Path>

@Override

public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)//重写文件访问方法

throws IOException {

if(file.toString().endsWith(".java")){

System.out.println(file.getFileName());

}

return FileVisitResult.CONTINUE;//返回继续扫描的结果

}

}

5.4、NIO文件系统IO

文件处理基础类

Files 可以让你轻松复制,移动,删除或处理文件的工具类WatchService 用来监视文件或目录的核心类,不管它们有没有变化

主要功能有:

创建和删除文件移动,复制,重命名和删除文件文件属性的读写文件内容的读取和写入处理符号链接用WatchService发出文件修改通知使用SeekableByteChannel——一个可以指定位置及大小的增强型字节通道。

文件的移动,复制,创建

//创建一个文件夹和一个文件

Path pathDir = Paths.get("d:/myTest");

Path pathDir2 = Paths.get("d:/myTest2");

Path pathFile = Paths.get("d:/myTest/test.text");

try {

if(!pathDir.toFile().exists()){

Files.createDirectories(pathDir);

}

if(!pathDir2.toFile().exists()){

Files.createDirectories(pathDir2);

}

if(!pathFile.toFile().exists()){

Files.createFile(pathFile);

}

//复制文件

Files.copy(pathFile, Paths.get("d:/myTest2/copyTest.text"),StandardCopyOption.REPLACE_EXISTING);

//移动文件

Files.move(pathFile, Paths.get("d:/myTest2/moveTest.text"),StandardCopyOption.REPLACE_EXISTING);

} catch (IOException e) {

e.printStackTrace();

}

文件属性  //获取文件相关属性

Path pathFile = Paths.get("d:/myTest/test.text");

try {

if(!Files.exists(pathFile)){

Files.createFile(pathFile);

}

System.out.println(Files.getLastModifiedTime(pathFile));

System.out.println(Files.size(pathFile));

System.out.println(Files.isSymbolicLink(pathFile));

System.out.println(Files.isDirectory(pathFile));

System.out.println(Files.readAttributes(pathFile, "*"));//输出全部属性

} catch (IOException e) {

e.printStackTrace();

}

一些相关特定文件系统的属性Java7也支持,如隐藏文件和链接文件

利用Files快速读取写入文件

Path file = Paths.get("d:/myTest/test.text");

try {

if(!Files.exists(file)){

Files.createFile(file);

}

//利用传统IO写入,读取

try(BufferedWriter bw = Files.newBufferedWriter(file, StandardCharsets.UTF_8, StandardOpenOption.APPEND)){

bw.write("This a test line,This is a test line.");

}

try(BufferedReader br = Files.newBufferedReader(file, StandardCharsets.UTF_8)){

String line;

while((line = br.readLine())!=null){

System.out.println(line);

}

}

//简化后的读取和写入

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

lines.add("\n this is writed by the simplified Files class");

lines.add("\n this is writed by the simplified Files 222");

Files.write(file, lines, StandardCharsets.UTF_8, StandardOpenOption.APPEND);

List<String> list = Files.readAllLines(file, StandardCharsets.UTF_8);

for(String str:list){

System.out.println(str);

}

} catch (IOException e) {

e.printStackTrace();

}

文件修改通知  在Java7中可以用java.nio.file.WatchService类监测文件或目录的变化。  //检测目录下文件有没有被修改

Path dir = Paths.get("d:/myTest");

try{

if(!Files.exists(dir)){

Files.createDirectories(dir);

}

WatchService watcher = FileSystems.getDefault().newWatchService();

//监测变化的key

WatchKey key = dir.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);

while(true){

WatchKey keys = watcher.take();

//得到下一个key的事件

for(WatchEvent<?> event: keys.pollEvents()){

//检测是否为监测事件

if(event.kind()==StandardWatchEventKinds.ENTRY_MODIFY){

System.out.println("File have been modified!!"+event.context());

}

}

//重新监测事件

key.reset();

}

}catch(final Exception e){

e.printStackTrace();

}

SeekableByteChannel  这个接口可能让开发人员能够改变字节通道的位置和大小。JDK中有一个java.nio.channels.SeekableByteChannel接口的实现类—java.nio.channels.FileChannel.这个类可以在文件读取或写入时保持当前位置。它具有寻址能力。

如读取一个文件的最后500个字符,在文件的一个位置覆盖一些内容

Path file = Paths.get("d:/myTest/test.text");

//设置一个缓冲区

ByteBuffer byteBuffer = ByteBuffer.allocate(512);

try {

//打开相关文件的FileChannel

FileChannel channel = FileChannel.open(file, StandardOpenOption.WRITE,StandardOpenOption.READ);

//读取文件最后500个字符到缓冲区

channel.read(byteBuffer, channel.size()-500);

//打印出读取的字符

System.out.println(new String(byteBuffer.array()));

//从倒数200的位置写入我的字符  写入会覆盖原来的相应位置字符的

String str = "****This inserted string********";

ByteBuffer bb = ByteBuffer.wrap(str.getBytes());

channel.write(bb, channel.size()-200);

//再读取文件最后500个字符到缓冲区

byteBuffer.flip();//清除缓存内容

channel.read(byteBuffer, channel.size()-500);

//再打印出读取的字符

System.out.println(new String(byteBuffer.array()));

} catch (IOException e) {

e.printStackTrace();

}

5.5、异步IO

异步IO是一种在读写操作结束前允许进行其他操作的IO处理

Java7的三个新的异步通道:

AsynchronousFileChannel —-用于文件IOAsynchronousSocketChannel —-用于套接字IO,支持超时AsynchronousServerSocketChannel —-用于套接字接受异步连接

使用新的异步IO api时,主要有两种形式,将来式和回调式

将来式  将来式用现有的Java.util.concurrent技术声明一个Future,用来保存异步操作的处理结果。通常用Future get()方法(带或不带超时参数)在异步IO操作完成时获取其结果。

AsynchronousFileChannel会关联线程池,它的任务是接收IO处理事件,并分发给负责处理通道中IO操作结果的结果处理器。跟通道中发起的IO操作关联的结果处理器确保是由线程池中的某个线程产生。

try{

Path path = Paths.get("D:/迅雷下载/ideaIU-14.0.3.exe");

//异步打开文件,用后台线程

AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

//读取100000000字节,采取并发处理

ByteBuffer buffer = ByteBuffer.allocate(100_000_000);

Future<Integer> result = channel.read(buffer, 0);

while(!result.isDone()){

//可以做点其它事情

System.out.println("Have not reading finish....,I can do some other things");

}

//获取结果

Integer byteRead = result.get();

System.out.println("Finish reading:"+byteRead);

}catch(Exception e){

e.printStackTrace();

}

回调式  回调式所采用的事件处理技术类似于Swing UI编程采用的机制。基本思想是主线程会派一个侦查员CompletionHandler到独立的线程中执行IO操作。这个侦查员将带着IO的操作的结果返回到主线程中,这个结果会触发它自己的completed或failed方法(要重写这两个方法)。在异步IO活动结束后,接口java.nio.channels.CompletionHandler会被调用,其中V是结果类型,A是提供结果的附着对象。此时必须已经有了该接口completed(V,A)和failed(V,A)方法的实现,你的程序才能知道异步IO操作成功或失败时该如何处理。

try{

Path path = Paths.get("D:/迅雷下载/ideaIU-14.0.3.exe");

//异步打开文件,用后台线程

AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

//读取100000000字节,异步回调处理

ByteBuffer buffer = ByteBuffer.allocate(100_000_000);

channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {

//读取完成时的回调方法

@Override

public void completed(Integer result, ByteBuffer attachment) {

System.out.println("Have read file finished:"+result);

}

//

@Override

public void failed(Throwable exc, ByteBuffer attachment) {

System.out.println("Read file failed:");

exc.printStackTrace();

}

});

System.out.println("Main thread can do something-----");

}catch(Exception e){

e.printStackTrace();

}

将来式和回调式的异步访问同样适用于AsynchronousServerSocketChannel和AsynchronousSocketChannel。我们可以用它们编写程序来处理网络套接字,比如语音IP。

5.6、Socket和Channel的整合

Java7推出了NetworkChannel,把Socket和Channel结合到一起。

java.nio.channels包 定义通道,表示连接到执行IO操作的实体,比如文件和套接字,定义用于多路传输,非阻塞IO操作的选择器java.net.Socket类 该类实现了客户端套接字,套接字是两个机器间通信的端点。

NetworkChannel  新接口java.nio.channels.NetworkChannel代表一个连接到网络套接字通道的映射。

SelectorProvider provider = SelectorProvider.provider();

try{

//将NetworkChannel绑定到3999端口上

NetworkChannel socketChannel = provider.openSocketChannel();

SocketAddress address = new InetSocketAddress(3999);

socketChannel = socketChannel.bind(address);

//检查套接字选项

Set<SocketOption<?>> socketOptions = socketChannel.supportedOptions();

System.out.println(socketOptions.toString());

//设置套接字Tos(服务条款)选项

socketChannel.setOption(StandardSocketOptions.IP_TOS, 3);

//获取SO_KEEPALIVE选项

Boolean keepAlive = socketChannel.getOption(StandardSocketOptions.SO_KEEPALIVE);

}catch(Exception e){

e.printStackTrace();

}

MulticastChannel  利用它可以实现多播功能,为了让新来的NetworkChannel加入多播组,Java7提供了一个新接口java.nio.channels.MulticastChannel及其默认实现类DatagramChannel.你可以很轻松地对多播发送和接收数据。

try {

//选择网络端口

NetworkInterface networkInterface = NetworkInterface.getByName("net1");

//打开DatagramChannel

DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET);

//将通道设置为多播

dc.setOption(StandardSocketOptions.SO_BROADCAST, true);

dc.bind(new InetSocketAddress(8080));

dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);

//加入多播组

InetAddress group = InetAddress.getByName("127.0.0.1");

MembershipKey key = dc.join(group, networkInterface);

} catch (Exception e) {

e.printStackTrace();

}

转载自:  http://wn398.github.io/2014/04/01/Java7%E4%B8%AD%E5%A2%9E%E5%8A%A0%E7%9A%84%E6%96%B0%E7%89%B9%E6%80%A7/

[转载] Java7中增加的新特性相关推荐

  1. 解读ASP.NET 5 MVC6系列(17):MVC中的其他新特性

    原文:解读ASP.NET 5 & MVC6系列(17):MVC中的其他新特性 (GlobalImport全局导入功能) 默认新建立的MVC程序中,在Views目录下,新增加了一个_Global ...

  2. Java1.5增加了新特性:可变参数

    /* Java 可变参数 Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理. 注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有 ...

  3. CSS3中的一些新特性(CSS)

    CSS3中的一些新特性 CSS3能做什么 边框 阴影 box-shadow 颜色 文字与字体 背景 CSS3中的动画 CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大 ...

  4. Python 3.11 中的最佳新特性和修正

    更快的解释器,更易懂的错误,更强大的类型提示,以及其他一系列的加速和调整,现在都可以试用了. Python 每年都会发布新版本,上半年是功能锁定的测试版,年底是最终版本. Python 3.11 的特 ...

  5. 详细解读Windows8.1 Update中的WIMBoot新特性

    微软在Windows8.1 Update发布免费更新后,越来越多win8系统用户选择了升级,在Windows8.1 Update全新系统中有一项WIMBoot新技术,面对新特性很多用户还是一筹莫展,不 ...

  6. php7.0 yield,PHP7中生成器的新特性 yield-from amp;amp; return-values

    生成器委托 简单地翻译官方文档的描述: PHP7中,通过生成器委托(yield from),可以将其他生成器.可迭代的对象.数组委托给外层生成器.外层的生成器会先顺序 yield 委托出来的值,然后继 ...

  7. 艾伟_转载:.NET 4.0新特性-- Corrupted State Exceptions

    作为程序员,我想很多人应该都有过跟异常打交道的经历.而且相信也有很多人也都写过catch(Exception e){//blabla}这种把所有未知异常一股脑儿捕获并处理掉的代码吧.不管是为敷衍客户也 ...

  8. Linux 4.10中两个新特性与我的一段故事

    今早5点半起来没有开始写文章,而是去西湾红树林连跑带走折腾了将近20公里,回来后就8点多了...洗了个澡之后坐稳当,开始写一段关于我的故事.         在2014年到2015年期间,我在负责研发 ...

  9. 前瞻:在 Java 16 中会带来哪些新特性?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 随着JDK 15的发布,计划于明年3月发布的JDK 16 ...

最新文章

  1. 使用pytest对django项目单元测试
  2. 一键让二次元老婆微笑,还能把猫脸变成狗脸,这篇CVPR 论文真有趣
  3. aitken插值方法的c++代码_无人驾驶路径规划技术-三次样条插值曲线及Python代码实现...
  4. 我为何爱读代码?你为何也应当爱?
  5. (模板)网页游戏用的“内容区”的“图赏影音”模板
  6. ExtJs 备忘录(1)—— Form表单(一) [ 控件使用 ]
  7. idea安装Translation翻译插件
  8. Spring Http Invoker使用简介
  9. 6. Observable 和 数组的区别
  10. 缓存穿透、缓存雪崩、缓存击穿的原因及解决方案
  11. Agile敏捷开发Planning Poker简介
  12. 网络工程师之子网划分
  13. Retinex算法,图像色彩增强之python实现——MSR,MSRCR,MSRCP,autoMSRCR
  14. 百词斩不复习_不背单词好用还是百词斩好用?
  15. iPad 升级失败后重新恢复出厂设置
  16. 《东周列国志》第九十二回 赛举鼎秦武王绝胫 莽赴会楚怀王陷秦
  17. AidLearning上手使用经验谈
  18. bzoj-2818 Gcd
  19. 对L1正则化和L2正则化的理解
  20. 51NOD 1024 矩阵中不重复的元素

热门文章

  1. C++中缀表达式求值(中缀表达式转后缀表达式)
  2. 南京高中计算机老师,正高级教师、江苏省高中信息技术特级教师——巫雪琴
  3. java 管道流_Java IO7:管道流、对象流
  4. php伪静态限制网页播放视频,php伪静态后html不能访问怎么办
  5. 液晶显示屏的C语言编码,单片机液晶汉字显示c语言程序
  6. python彩票预测与分析_130期祥子大乐透预测奖号:后区大小分析
  7. 计算机网络—UDP协议
  8. [Python] random.uniform( ) 函数教程与实例解析
  9. java使用BZip算法压缩解压缩文件、数据流、byte[]字节数组
  10. Echarts数据可视化radar雷达坐标系,开发全解+完美注释