JAVA7(JDK1.7) 新特性一览(备忘或者速查)

JAVA开发 workingTime 460℃ 0评论

写这篇文章的目的:传统企业,大部分还在用JAVA-6,互联网公司,大部分在使用JAVA-7,JAVA-8还不太普及,所以JAVA-7还不过时,并且有好多人,即便上了JAVA-7或8,也不使用新的特性。so,这篇文章算是一个说明,或者参考吧。

基础语法的改变

一、switch语句中的String

在java6中,switch语句中的case中的常量只能是byte/char/short/int,或者是枚举常量。java7中新增加了String类型,这使得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");  
   }  
}  

二、二进制文本

在java7之前,如果想处理二进制,就必须借助棘手的基础转换。比如:想让int x用位模式表示十进制102,需要如下方式

//102的二进制是1100110
int x = Integer.parseInt("1100110" ,2); //java7之前语法
int x_new = 0b1100110; //java7语法
/**
*加0b表示二进制
*加0 表示八进制
*加0x表示十六进制
*/

三、数字中的下划线

java7中允许将过长的数组用“_”隔开,以便阅读。例如:

long a = 23_23_98L; //输出232398L

四、改善后的异常处理

异常处理有两处改进 —— multicatchfinal重抛

  • multicatch
try {

}catch (FileNotFoundException | UnknownHostException e){
    //文件类异常和主机类异常
}catch (IOException ex){
    //IO异常
}

就是比如需要抛出多个异常的时候,可以讲多个异常合并到一个catch中。

  • final重抛

所谓final重抛就是当我们catch异常的时候,偷懒使用Exception强制替换多个异常类型时,异常的真是类型将会被覆盖。
如果使用我们如下方式:

try {

}catch (final Exception e){
    
}

这样,不仅可以偷懒,而且还可以抛出真实的异常类型。

  • try-with-resources(TWR)

TWD:是把资源的作用域限定在代码快内,当程序离开这个代码快时,资源会被自动关闭。(这个真的很重要,因为没人会在手动关闭资源时100%正确。并且,JDK中有三分之二的close()用法都有Bug。)

public void writeFile(File file){
   try (OutputStream out = new FileOutputStream(file)){
       out.write(new byte[4096]);
   } catch (FileNotFoundException e) {
       e.printStackTrace();
   } catch (IOException e) {
       e.printStackTrace();
   }
}

在try语句块中,构建资源,使用完后,会自动关闭。但是需要注意,不可以这么写:

try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("aaa.txt"))){
            
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

原因在于如果“aaa.txt”文本不存在,或者出现问题,FileInputStream是无法关闭的,只能关闭ObjectInputStream,所以需要分开构建。

try (FileInputStream fi = new FileInputStream("aaa.txt");
ObjectInputStream in = new ObjectInputStream(fi)){

} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

五、实现equals、hashCode和CompareTo方法

  • 安全的比较

在进行对象比较的时候,比如要比较两个String的对象是否相等,JAVA6的实现方式:

String a = null;
String b = "aa";
String d = "aa";

System.out.println("a==b?" + a.equals(b));
System.out.println("b==a?" + b.equals(a));
System.out.println("b==d?" + b.equals(d));

第一个输出语句,结果是抛出:java.lang.NullPointerException
第二个输出语句,结果是false
第三个输出语句,结果是true

so,在java6的时候,我们比较对象时,还需要判断一下对象时候为null,相当蛋疼。来看看JAVA7的改进吧

String a = null;
String b = "aa";
String d = "aa";

System.out.println("a==b?" + Objects.equals(a,b));
System.out.println("b==d?" + Objects.equals(b,d));

第一个输出语句,结果是false
第二个输出语句,结果是true

来看下Objects.equals()的远吗,一目了然:

public static boolean equals(Object a, Object b) {
   return (a == b) || (a != null && a.equals(b));
}
  • 比较数值类型

JAVA7之前,在进行计算时会出现这样的问题,比如:

public static String compare(int x ,int y){
   int diff = x - y;
   if (diff > 0) return "x > y";

   return "x < y";
}

public static void main(String[] args) {
   
   int x = 2147000000;
   int y = -483650;
   System.out.println(Test.compare(x , y));
}

按理说,返回结果应该是:"x > y"。可是,输出的结果偏偏是:"x < y"。
为什么呢?原因在于,int类型的范围是:-2147483648~2147483647,计算结果超出范围了,diff=-2147483646。解决方案是:将int diff = x-y;改成int diff = new Integer(x).compareTo(y);

JAVA7的解决方案简化了这一操作:int diff = Integer.compare(x,y);

不只是int,Short,Long,Byte,Boolean均有该方法。

六、其他改进

  • 计算HASH码

Objects.hash(a,b...); 可以传入可变参,生成hash码。

  • NULL 检查
Objects.requireNonNull(null);
Objects.requireNonNull(null,"this is null");

requireNonNull()方法不仅方便检查对象是否为null,还可以输出自定义的异常语句。这样可以快速定位问题地点。

  • 全局日志打印

System.out.println()带来的问题:会严重影响服务器性能,比如我们使用Tomcat作为web容器,输出语句会频繁向log日志中频繁写入,访问量越大,写入量就越大。
Log日志的优势:可以控制日志级别,在上线的系统中打印error级别的日志,在开发环境打印全部级别等等。高级的日志系统还可以做到将日志输出到指定文件,并且控制文件大小等功能。

public static void main(String[] args) throws IOException, InterruptedException {
    //Level级别有  信息:INFO、警告:WARNING、严重:SEVERE、禁用:OFF
   Logger.getGlobal().log(Level.INFO,"打印一条INFO日志。");
}
  • 执行外部命了的方法

JAVA执行linux命令或者DOS命令的方式。不仅可以执行,还可以将结果定向输出。

public static void main(String[] args) throws IOException, InterruptedException {
   //每个空格隔开的命令,就是一个字符串。比如linux命令:ls -al,在ProcessBuilder中就是new ProcessBuilder("ls","-al")
   ProcessBuilder builder = new ProcessBuilder("grep","-o","[A-Za-z][A-Za-z_0-9]*");
   //将标准输入、输出和错误流重定向到文件中
   builder.redirectError(Paths.get("Error.java").toFile());
   builder.redirectInput(Paths.get("Input.java").toFile());
   builder.redirectOutput(Paths.get("Input.java").toFile());
   //将结果输出到控制台
   builder.inheritIO();
   //执行
   builder.start().waitFor();

}

NIO.2


import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;

/**
 * User: R&M www.rmworking.com/blog
 * Date: 17/1/3
 * Time: 21:16
 * Test
 * org.thinkInJava
 */
public class FileOperation {

    /**
     * 文件读写操作
     *
     * @param fileName
     * @throws IOException
     */
    public void fileWriteAndRead(String fileName) throws IOException {
        Path p = Paths.get(fileName);
        System.out.println("文件夹名称: " + p.getFileName());
        System.out.println("父路径名称: " + p.getParent());
        System.out.println("根路径名称: " + p.getRoot());

        //将字符串写入文件
        String content = "测试JAVA7的文件写入功能!!!";
        Files.write(p, content.getBytes(StandardCharsets.UTF_8));
        //按照行来写入文件,并且追加到原文件末尾
        List<String> lines = new ArrayList<>();
        lines.add("苹果。。。");
        lines.add("香蕉。。。");
        lines.add("橙子。。。");
        Files.write(p, lines, StandardOpenOption.APPEND);

        //文件读取
        byte[] bytes = Files.readAllBytes(p);
        String result = new String(bytes, StandardCharsets.UTF_8);
        System.out.println(result);
    }

    /**
     * 文件夹操作
     *
     * @param filePath
     * @throws IOException
     */
    public void fileOperation(String filePath) throws IOException {
        Path p = Paths.get(filePath);
        //判断父目录是否存在,如果不存在则创建
        System.out.println(Files.exists(p.getParent()));
        if(Files.exists(p.getParent())){
            Files.createDirectory(p);
        }else{
            Files.createDirectories(p);
        }

    }

    /**
     * 删除文件或文件夹
     * @param fileNames
     * @throws IOException
     */
    public void delFies(String... fileNames) throws IOException {
        for (String fileName : fileNames){
            Path p = Paths.get(fileName);
//            if(Files.exists(p)){
//                Files.delete(p);  //这个方法是需要判断是否存在目录的
//            }
            //这个方法是可以允许空文件或者文件夹
            Files.deleteIfExists(p);
        }
    }

    public static void main(String[] args) throws IOException {
        FileOperation fo = new FileOperation();
        String fileName1= "XXX/demo.txt";
        String fileName2 = "XXX/demo";
        fo.fileWriteAndRead(fileName1);
        fo.fileOperation(fileName2);

        fo.delFies(fileName1 , fileName2);



        /**其他还有一些 Files
         * Files.move(p); 移动文件
         * Files.copy(); 复制一个文件
         * Path p = Files.createTempFile(null, ".TXT");//创建一个临时文件
         * System.out.println(p.getParent() + "/" + p.getFileName());
         * Path p = Files.createDirectory(Paths.get(fileName1));//创建一个临时文件夹
         * */
    }

}

转载请注明:R&M » JAVA7(JDK1.7) 新特性一览(备忘或者速查)

喜欢 (0)or分享 (0)
发表我的评论
取消评论

表情

联系我:rm@rmworking.com