java技术加强之其他1.5特性

来源:互联网 发布:als推荐算法 编辑:程序博客网 时间:2024/05/22 16:49

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效、清晰,安全的代码。

①静态导入
②自动装箱/拆箱
③增强for循环
④可变参数
⑤枚举
⑥反射
⑦注解
⑧泛型
静态导入
JDK 1.5 增加的静态导入语法用于导入类的某个静态属性或方法。使用静态导入可以简化程序对类静态属性和方法的调用。它完全是为了便利而增加的新特性
语法:

Import static 包名.类名.静态属性|静态方法|*

例如:

import static java.lang.System.out //静态导入类成员import static java.lang.Math.* //使用通配符

静态导入—小细节

import static java.util.Arrays.sort;import static java.util.Collections.sort;

这是允许的,运行时会根据参数来自动找到对应的方法。
注:如果导入的两个静态方法的参数也是一样的话,由于不能确定是哪个方法,所有使用时需要小心
自动装箱/拆箱
Java中的基本类型不是对象,因此包装类用来当做对象版本的基本类型。当你要在两者之间来来回回转换时,事情就变得很讨厌了。如下所示:
这里写图片描述

自动装箱:指开发人员可以把一个基本数据类型直接赋值给对应的包装类。Autoboxing

自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型。Autounboxing

典型应用:

这里写图片描述

思考:
Integer i = null;
int j = i;
语法有无错误,能否运行?
i被赋值为null是合法的,然后i被拆箱给j,然而null对基本类型来说是不合法的,运行会抛出NullPointerException

自动装箱/拆箱—细节1
Java的规范指出:特定的基本类型一定得被box成相同的包装类型。这些对象会被高速缓存以重复使用,并且会被当做一般对象使用。这些特殊的值是boolean值的true和false、所有的byte值、介于-128至127的short与int值,以及介于\u0000与\u007F之间的任何一个char。
这里写图片描述

分别输出truetruefalsefalse

自动装箱/拆箱—细节2
在一般的情况下,Java借由使用方法的名称来调用method。在方法有重载的情况下,需要检查方法的参数来决定调用哪个方法,如果没有找到符合的参数,会出现编译错误。

public void doSomething(double num);public void doSomething(Integer num);调用doSomething():int foo = 1;doSomething(foo);//结果调用哪个方法呢?

想知道答案吗?自己动手试一下。。。

*在5.0中的方法调用都会选出与在1.4中所选出的相同的方法。
也就是说编译器会试着不用任何的装箱/拆箱来定位方法。
编程时应尽可能地保持精确就可以避开这个问题。*

增强for循环
增强for循环又称为“foreach”或“enhanced for”循环
抛弃迭代:在JDK5以前的版本中,遍历数组或集合中的元素,需先获得数组的长度或集合的迭代器,比较麻烦!
因此JDK5中定义了一种新的语法——增强for循环,以简化此类操作。增强for循环只能用在数组、或实现Iterable接口的子类上
语法格式:

for(变量类型 变量 :需迭代的数组或集合)    }
int arr[] = new int[5];for(int num : arr){    num = 1;}System.out.println(arr[0]);答案:0List<String> list = new ArrayList<String>();        list.add("xxx");        for(String str : list){            str = "yyy";        }        System.out.println(list.get(0));答案:xxx解析:增强for循环只适合取数据,但是你要去修改是有办法的?想一想,什么的才可以使用增强for循环

可变参数
可变参数(variable argument)允许你指定可以采用多个同类型参数的方法,而不需要事先确定参数的数目。

可变参数。语法:        public void foo(int … args){        }

注意事项:
调用可变参数的方法时, 编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数
在一个方法参数中只能使用一个省略号;且省略号必须出现在方法中参数列表的最后一个位置。
思考一下:
这里写图片描述
这里写图片描述

不可变类
不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值。在JDK的基本类库中,所有基本类型的包装类,如Integer和Long及String,都是不可变类。如果创建了他们的对象,在程序代码中无法再改变这些对象的值,因为他们没有提供修改属性的方法

注释:
*不可变类能是程序更加安全,不容易出错
不可变类是线程安全的,当多个线程访问不可变类的同一个实例时,无需进行线程同步。*


没有提供修改的方法,仅仅是读取,我怕你什么线程安不安全啊。


用户自定义不可变类

1、把属性private final类型
2、不对外公开修改属性的set方法,只提供get方法
3、在构造方法中初始化所有属性
4、覆盖Object类的equals和hashCode方法

在创建不可变类时,假如它的属性的类型是可变类型,在必要的情况下,必须提供保护性拷贝,否则,这个不可变类实例的属性仍然有可能被错误地修改。看以下代码:
这里写图片描述
这里写图片描述
尽管Schedule类的start和end属性是final类型的,但由于它们引用Date对象,在程序中可以修改所引用Date对象的属性。

不可变类—改进
这里写图片描述
通过采用保护性拷贝,其他程序无法获得与Schedule对象关联的Date对象的引用
如果Schedule类中被final修饰的属性所属的类是不可变类,就无需提供保护性拷贝,因为该属性所引用的实例值永远不会被改变
枚举类
为什么需要枚举?
一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,比如成绩Grade只能为ABCDE。此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。

JDK 5新增的 enum 关键字用于定义一个枚举类。
一个枚举也可以有构造函数、字段和方法

这里写图片描述
带抽象方法的枚举
这里写图片描述

枚举类具有如下特性:
①枚举类也是一种特殊形式的Java类。
②枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
③与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。
④枚举类也可以实现接口、或继承抽象类。
⑤JDK5中扩展了swith语句,它除了可以接收int, byte, char, short外,还可以接收一个枚举类型。
⑥若枚举类只有一个枚举值,则可以当作单态设计模式使用。
这里写图片描述

Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:
name()
ordinal()
valueof(String name)此方法虽然在JDK文档中查找不到
values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便。

package cn.itcast.base.enumeration;public enum WeekDay {    MON{        public String toLocaleString() {            return "星期一";        }    },TUE{        public String toLocaleString() {            return "星期二";        }    },WED{        public String toLocaleString() {            return "星期三";        }    },THU{        public String toLocaleString() {            return "星期四";        }    },FRI{        public String toLocaleString() {            return "星期五";        }    },SAT{        public String toLocaleString() {            return "星期六";        }    },SUN{        public String toLocaleString() {            return "星期日";        }    };    public abstract String toLocaleString();}//枚举中的常用方法:自定义的枚举类的爸爸是java.lang.Enum    @Test    public void test3(){        WeekDay wd = WeekDay.FRI;        String name = wd.name();//枚举类型对应的字符串名称        System.out.println(name);        答案:输出FRI        String str = "MON";        WeekDay wd1 = WeekDay.valueOf(str);        System.out.println(wd1.toLocaleString());        WeekDay wd2 = WeekDay.SUN;        System.out.println(wd2.ordinal());        答案:6//返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。    }    @Test    //特殊的属性values:返回所有的枚举值。API中看不到的    public void test4(){        WeekDay [] wds = WeekDay.values();        for(WeekDay wd:wds){            System.out.println(wd.name());        }    }
0 0
原创粉丝点击