Java高新技术(一)之jdk5以及7的新特性


IDE工具介绍

IDE即集成开发环境。下面我们来说说各种IDE工具介绍

1.      NetBeans   官网网址为:http://netbeans.org/

2.      JBuilder.    不存在了

3.      IntellijIDEA   这个被评为世界上最好的IDE官网网址:http://www.jetbrains.com/

4.      Eclipse(日蚀,月蚀)官网网址:http://www.eclipse.org/

5.      Myeclipse  后面讲Java EE需要用到官网网址:http://www.myeclipseide.com/,可能中国大陆访问不了,需要翻墙工具

 

java新特性

JDK1.5新特性

1.      泛型(Generics

这里是我详细讲泛型的,此处不赘述

 http://blog.csdn.net/lsh609912726/article/details/8197718

2.      静态导入

格式: import static要导入的包名

作用:不用再写类.静态方法,直接写此类的静态方法即可,注意就是导入的包名必须精确到要导入某个类,而且必须是此类的静态方法,非静态不可以这样做

 

例如:

static import java.lang.Math;

如:double a=abs(12.36);

           int b=max(2,3);

上面两个都没写类,这是在jdk1.5以后是可取的

 

3.      增强for循环

增强for循环也叫for-each循环,简化了集合与数组的遍历

语法:for (类型名变量名:数组(集合)变量名){

                            code

};

我们通过代码演示看看,增强for循环在集合和数组的用法:

importjava.util.ArrayList;

importjava.util.Iterator;

 

publicclass SuperFor {

 

         public static void main(String[] args){

                   arr_1();

                   arr_2();

                   list();

         }

        

         /*

          *一维数组遍历

          */

         public static void arr_1() {

                   int[] arr=newint[]{1,2,3,4,5};

                   //旧式遍历

                   for (inti=0;i<arr.length;i++){

                            System.out.println(arr[i]);

                   }

                   System.out.println("-----------------");

                   //新式遍历,增强for循环

                   for (int elements:arr){

                            System.out.println(elements);

                   }

         }

         /*

          * 二维数组遍历

          */

         public static void arr_2(){

                   int[][]arr={{1,2,3},{2,3,4},{4,5,6}};

                  

                   for (int[] i:arr){

                            for (int arrs:i){

                                     System.out.println(arrs);

                            }

                   }

         }

         /*

          * 集合遍历,三种方式

          */

         public static void list(){

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

                   list.add("one");

                   list.add("two");

                   list.add("three");

                  

                   //旧式遍历1

                   for (Iterator<String>it=list.iterator();it.hasNext();){

                            System.out.println(it.next());

                   }

                   System.out.println("-----------------");

                   //旧式遍历2

                   for (inti=0;i<list.size();i++){

                            System.out.println(list.get(i));

                   }

                   System.out.println("-----------------");

                   //新式遍历,增强for循环

                   for (String lists:list){

                            System.out.println(lists);

                   }

         }

}

注意:当增强for循环遍历集合和数组时,如果需要访问集合或数组的下标,那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的for循环,因为它丢失了下标信息。

 

4.      可变参数

可变参数使程序员可以声明一个接受可变参数目参数的方法。

格式:声明方法(类型参数名);

         比如int…等价于int[],可变参数不仅可以传类型参数,也可传一个数组。

代码演示如下:

publicclass CanChange {

 

publicstaticvoid main(String[]args) {

    sum_1(1,2,3,4);

    sum_2("可变参数",1,2,3,4);

}

publicstaticvoid sum_1(int... i)

{

    for (int a:i){

       System.out.println(a);

    }

}

publicstaticvoid sum_2(String str,int... i)

{

    for (int a:i){

       System.out.println(str+a);

    }

}

}

 

所以可变参数本质上就是一个数组某个声明了可变参数的方法来说,我们既可以传递离散的值,也可以传递数组对象。但如果将方法中的参数定义为数组,那么只能传递数组对象而不能传递离散的值

注意:可变参数必须要作为方法参数的最后一个参数,即一个方法不可能具有两个或两个以上的可变参数

 

5.      自动装箱和拆箱(Autoboxing/unboxing

自动装箱:基本类型自动转为包装类(如:int->>Interger

自动拆箱:包装类自动转为基本类型(如:iInterger->>int

 

我们通过以下代码,可以看出自动装箱和拆箱的基本应用

publicclass BoxTest {

 

public static void main(String[] args) {

                    Integer a=100;

                   intb=100;

                    if (a==b){

                             System.out.println("a=b");

                    }else {

                             System.out.println("a!=b");

                    }

}

}

 

注意:当我们把ab的值改为200,会打印a=b;原因在于:Interger类有一个缓存,它会缓存介于-128~127之间的整数。而这个范围是byte类型范围,所以大于这个范围,等于byte新创了个对象,两个对象的地址是不一样的,所以打印a=b

 

枚举(Enumeration

枚举基本概念

jdk1.5引入了一个全新类型的“类“-枚举类型,引入了一个新关键字enum,被关键字修饰的名字就是枚举类型

格式如下:

public enum Color

{

     Red, White, Blue

}

使用方法是:Color myColor =Color.Red;

 

枚举的两个方法:

a)  类型数组[] values():获取枚举里的值

b)  valueOfString str):将一个字符串转化为对应的枚举类型的

 

我们来看看枚举的基本代码演示:

publicenum Color {

White,Red,Blue;

}

publicclass EnumDemo {

   publicstaticvoid main(String[] args) {

      Color c = Color.Red;

      System.out.println(c);

      System.out.println("--------------");

      /*

       * 遍历枚举里的每个值

       */

      for (Color co:Color.values()){

        System.out.println(co);

      }

   }

}

 

枚举的在switch语句的应用:

publicenum OpConstant {

TURN_RIGHT,TURN_LEFT,SHOOT

}

publicclass OpConstantDemo {

   publicstaticvoid main(String[] args) {

      demo(OpConstant.SHOOT);

   }

   publicstaticvoid demo(OpConstant op){

      switch (op) {

      caseTURN_RIGHT:

        System.out.println("向左转");

        break;

      caseTURN_LEFT:

        System.out.println("向右转");

        break;

      caseSHOOT:

        System.out.println("射击");

        break;

      default:

        break;

      }

   }

}

 

注意:我们所定义的每个枚举类型都继承自java.lang.Enum类,枚举中的每个成员默认都是public static final的修饰;而每个枚举的成员其实就是你定义的枚举类型的一个实例(Instance),换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么?在运行期间我们无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定下来了。

 

我们看看如下代码演示下

publicenum Coin {

   //由于构造方法是带参数的,所以声明的时候就必须传个String参数

   peen("hello"),nickel("world"),dime("welcome"),quarter("haha");

  

   private Stringvalue;

   public String getValue(){

      returnvalue;

   }

  

   //类似类的构造方法

   Coin(String value){

      this.value=value;

   }

  

   publicstaticvoid main(String[] args) {

      //通过其中的一个成员变量,获得其一的对象

      Coin co=Coin.quarter;

      //获得此对象的值

      System.out.println(co.getValue());

   }

}

 

小应用:用枚举来实现访问控制,只能让管理员进入

publicclass AccessControl {

   publicstaticvoid main(String[] args) {

      Role r=Role.valueOf("ADMIN");

      System.out.println(accessControl(r));

   }

 

   publicstaticboolean accessControl(Role r) {

      if (r == Role.ADMIN) {

        returntrue;

      } elseif (r == Role.TEACHER) {

        returnfalse;

      } else {

        returnfalse;

      }

   }

}

enum Role {

   ADMIN,TEACHER,STUDENT

}

 

 

枚举集合

EnumSet是集合集成枚举的一个类,这个类有一些常用的方法:

a) abstract Iterator<E> iterator() :返回的迭代器按其自然顺序遍历这些元素

b) static <E extends Enum<E>>EnumSet of(E e,E…e):创建一个最初包含指定元素的枚举 set

c) static <E extends Enum<E>>EnumSet complementOf(EnumSet<E> s):创建一个其元素类型与指定枚举 set相同的枚举 set,最初包含指定 set中所不包含的此类型的所有元素

d) static <E extends Enum<E>>EnumSet noneOf(Class<E>elementType):创建一个具有指定元素类型的空枚举 set

 

我们代码演示下遍历枚举集合的演示:

import java.util.EnumSet;

import java.util.Iterator;

 

enum FontEnum {

   RED,YELLOW,BLUE,BLACK

}

 

publicclass Test1 {

  

   publicstaticvoid main(String[] args) {

      EnumSet<FontEnum> set=EnumSet.of(FontEnum.YELLOW, FontEnum.BLACK);

      ergodic(set);

      System.out.println("-------------");

      System.out.println(EnumSet.complementOf(set));

   }

   publicstaticvoid ergodic(EnumSet<FontEnum> set) {

      for (Iterator<FontEnum> it = set.iterator();it.hasNext();) {

        System.out.println(it.next());

      }

   }

/*

这里面是noneof方法使用

publicstaticvoid main(String[] args) {

      EnumSet<FontEnum> set=EnumSet.noneOf(FontEnum.class);

      set.add(FontEnum.BLUE);

      set.add(FontEnum.YELLOW);

      ergodic(set);

   }

*/

}

 

EnumMap也是枚举的一个典型的类:它的常用方法:

a) 构造方法:EnumMap(Class<K> keyType):创建一个具有指定键类型的空枚举映射。

b) V put(K key, V value):将指定值与此映射中指定键关联

c) V get(Object key):返回指定键所映射的值,如果此映射不包含此键的映射关系,则返回 null

我们基本演示下EnumMap的用法:

import java.util.EnumMap;

import java.util.Map;

 

public class MapEnum {

   publicstatic void main(String[] args) {

      Map<Action,String>map=new EnumMap<Action,String>(Action.class);

      map.put(Action.TURN_LEFT,"向右转");

      map.put(Action.SHOOT,"射击");

      map.put(Action.TURN_RIGHT,"向左转");

      for(Action actions:Action.values()){

        System.out.println(map.get(actions));

      }

   }

}

 

enum Action{

   TURN_RIGHT,TURN_LEFT,SHOOT

}

 

注解(Annotation

每一个注解都是一个类,使用每一个注解类都是创建一个实例,注解相当于一种标记。有什么标记,程序就做什么。

 

四个基本注解

@Override:用来指定方法重载的,它可以强制一个子类必须覆盖父类的方法

@Deprecated:它用于表示程序的类,方法等已过时,编译时会发生警告

@SupperessWarnning:取消指定的编译器警告

@SafeVaragsJava7新增注解,即堆污染(Heappollution),即把一个不带泛型的变量赋给带泛型的变量就会发生污染。

 

元注解(Meta Annotation

元注解都是修饰其他注解的定义

java中也提供了四种元注解

@Retention:指定的被修饰的Annotation可以保留多少时间

value值:

a)   RetentionPolicy.Class:保留在class文件中,运行java时,不再保留,这是默认值

b)   RetentionPolicy.Runtime:保留在class文件中,一直保留到运行时

c)   RetentionPolicy.Source:只保留在源文件中,编译器直接丢弃

@Target指定修饰程序的什么成分

value值:

a) ElementType. ANNOTATION_TYPE:只能修饰注释

b) ElementType. CONSTRUCTOR:只能修饰构造方法

c) ElementType. FIELD:只能修饰成员变量

d) ElementType. LOCAL_VARIABLE:只能修饰局部变量

e) ElementType. METHOD:只能修饰方法

f)  ElementType. PACKAGE:只能修饰包

g) ElementType. PARAMETER:可以修饰参数

h) ElementType. TYPE:可以修饰类,接口

@Documented:将会被javadoc工具提取成文档

@Inherited:将会具有继承性

 

自定义注解

当我们自定义注解时,总共有三个步骤:

a) 注解类,形式如下

@interface A{}

b) 应用了注解类,形式如下:

@A

class B{}

c) 对应用了注解类的类进行反射操作的类,形式如下:

Class C{

B.class.isAnnotationPresent(A.class)

A a=B.class.getAnnotation(A.class)

}

 

我们还可以为注解增加各种属性,代码演示如下:

我们先自定义一个注解类

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public@interfaceAnnotionDemo {

  //我们自定义一个值,默认是blue

  String color()default"blue";

  //这是Annotation默认设的值

  String value();

  //自定义数组的值,并放入默认数组的值

  int[] array()default {1,3,4};

  //自定义注释值

  MetaAnnotation annoAttriute()default@MetaAnnotation("ly");

}

public@interfaceMetaAnnotation {

  String value();

}

 

应用注解类

publicclass AnnotationTest {

  @SuppressWarnings(value="unchecked")

  publicstaticvoid main(String[] args) {

     System.runFinalizersOnExit(true);

     if (AnnotationTest.class.isAnnotationPresent(AnnotionDemo.class)){

       AnnotionDemo anno=AnnotationTest.class.getAnnotation(AnnotionDemo.class);

       //打印设定color的值

       System.out.println(anno.color());

       //打印设定value

       System.out.println(anno.value());

       //打印数组的长度

       System.out.println(anno.array().length);

       //打印注释的注释的值

       System.out.println(anno.annoAttriute().value());

     }

  }

}

JDK1.7新特性

1.二进制字面量,

可以用二进制来表示整数(byte,short,intlong)它可以使代码更容易理解,语法也非常简单:

语法:

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;

注意:你只能将下划线置于数字之间

 

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

以下代码演示:

public class SwitchDemo {

   public staticvoid main(String[] args) {

      String str ="秋天";

      switch (str) {

      case "春天":

        System.out.println("春天");

        break;

      case "夏天":

        System.out.println("夏天");

        break;

      case "秋天":

        System.out.println("秋天");

        break;

      case "冬天":

        System.out.println("冬天");

        break;

      }

   }

}

 

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

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

 

//例如

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

//可以简化为

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

 

5.try-with-resources语句

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

static String readFirstLineFromFile(String path) throwsIOException {

try (

BufferedReader br =

new BufferedReader(new FileReader(path))) {

return br.readLine();

}

}

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

try (

java.util.zip.ZipFile zf =

 newjava.util.zip.ZipFile(zipFileName);

java.io.BufferedWriter writer =

java.nio.file.Files.newBufferedWriter(outputFilePath,charset)

) {

}catch(…){

}finally{

}

Catch多个Exceptionrethrowexception改进了类型检测

很多时候,我们捕获了多个异常,却做了相同的事情,比如记日志,包装成新的异常,然后rethrow。这

时,代码就不那么优雅了,例如

catch (IOException ex) {

logger.log(ex);

throw ex;

catch (SQLException ex) {

logger.log(ex);

throw ex;

}

Jdk7允许捕获多个异常

catch (IOException|SQLExceptionex) {

logger.log(ex);

throw ex;

}

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

Rethrow Exception更具包容性的类型检测

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

只需在方法定义的时候声明需要抛出的异常即可

public void call() throwsReflectiveOperationException, IOException {

try {

callWithReflection(arg);

} catch (final Exception e) {

logger.trace("Exception in reflection", e);

throw e;

}

}

6.IO流中NIO2.0文件系统

jdk7 IO流有了一个新的包就是NIO包,此包是对文件的详细用法

 文件系统改善了以往File的弊端。

比如Path类来处理路径(文件和目录),包括:

创建pathPaths.get(String s)

获得path的详细信息 getName(),getXX()

删除path的冗余信息 toRealPath

转换pathtoAbsolutePath()

合并两个pathresolve()

在两个path之间创建相对路径 relativeze()

比较路径 equal()startsWith(),endWith()

 

File持各种文件操作,包括

移动文件,

复制文件,

删除文件,

更详细的文件属性,包括文件权限,创建者,修改时间……

Walking the File Tree(递归遍历文件树)

Watch a Directory for Change (监听文件更改)

 

注:jdk7新特性一部分取自网络资料,此学习笔记仅供个人复习查阅之用。



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值