JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)
JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效、清晰,安全的代码。
这些新特性主要有:
1.静态导入
2.自动装箱/拆箱
3.增强for循环
4.可变参数
5.枚举
6.泛型
7.元数据
1.静态导入
静态导入用于简化程序对静态属性和方法的调用
语法:Import static 包名.类名.静态属性|静态方法|*
例如:
import static java.lang.System.out
import static java.lang.Math.*
2.自动装箱/拆箱
自动装箱:指开发人员可以把一个基本数据类型直接赋给对应的包装类。
自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型。
Integer i = 1; //装箱
int j = i; //拆箱
典型应用:
List list = new ArrayList();
list.add(1);
int j=(Integer)list.get(0);//拆箱
3.增强for循环
引入增强for循环的原因:在JDK5以前的版本中,遍历数组或集合中的元素,需要先获得数组的长度或集合的迭代器,比较麻烦!
JDK5中定义了一种新的语法--增强for循环,以简化此类操作。增强for循环只能在数组或实现Iterable接口的集合类上。
语法格式:
for(变量类型 变量:需要迭代的数组或集合){
}
代码:
@Test
public void test1() {
int arr[] = { 1, 2, 3 };
for (int num : arr) {
System.out.println(num);
}
}
输出:
1
2
3
@Test
public void test2() {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
for (Object obj : list) {
int i=(Integer)obj;
System.out.println(i);
}
}
输出:
1
2
3
@Test
public void test3() {
Map map=new HashMap();// HashMap按hash函数保存数据,保存的数据与存的顺序可能不一样
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
//传统方式1
Set set=map.keySet();
Iterator it =set.iterator();
while(it.hasNext()){
String key=(String)it.next();
String value=(String)map.get(key);
System.out.println(key+"="+value);
}
}
输出:
3=ccc
2=bbb
1=aaa
@Test
public void test4() {
Map map=new LinkedHashMap();
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
//传统方式1
Set set=map.keySet();
Iterator it =set.iterator();
while(it.hasNext()){
String key=(String)it.next();
String value=(String)map.get(key);
System.out.println(key+"="+value);
}
}
输出:
1=aaa
2=bbb
3=ccc
@Test
public void test5() {
Map map = new LinkedHashMap();
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
// 传统方式2
Set set = map.entrySet();
Iterator it = set.iterator();
while (it.hasNext()) {
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println(key + "=" + value);
}
}
输出:
1=aaa
2=bbb
3=ccc
@Test
public void test6() {
Map map = new LinkedHashMap();
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
// 增强for取map的第1种方式
for (Object obj : map.keySet()) {
String key = (String) obj;
String value = (String) map.get(key);
System.out.println(key + "=" + value);
}
}
输出:
1=aaa
2=bbb
3=ccc
@Test
public void test7() {
Map map = new LinkedHashMap();
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
// 增强for取map的第2种方式
for (Object obj : map.entrySet()) {
Map.Entry entry = (Entry) obj;
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println(key + "=" + value);
}
}
输出:
1=aaa
2=bbb
3=ccc
// 使用增强for需要注意的问题:增强for只适合取数据,要修改数组或集合中的数据,要用传统方式
@Test
public void test8() {
int arr[]={1,2,3};
for(int i:arr)
{
i=10;
}
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
List list = new ArrayList();
list.add("1");
for(Object obj:list)
{
obj=10;
}
System.out.println(list.get(0));
}
输出:
1
2
3
1
4.可变参数
测试JDK中具有可变参数的类Arrays.asList()方法。分别传多个参、传数组,传数组又传参的情况。
注意:传入基本数据类型数组的问题
从JDK5开始,Java允许为方法定义长度可变的参数。语法:
public void foo(int ...args){
}
注意事项:
调用可变参数的方法时,编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数
可变参数只能处于参数列表的最后,所以一个方法最多只能有一个长度可变的参数
代码:
@Test
public void testSum() {
sum(1,2,3,4,5,6);
}
public void sum(int ...nums) {
//可变参数你把他看成数组
int sum=0;
for(int i:nums){
sum+=i;
}
System.out.println(sum);
}
输出:
21
@Test
public void testAa() {
aa(1,2,3,4,5,6);
}
//可变参数需要注意的问题:public void aa(int ...nums,int x) { 这样不行,参数会被直接看成一个数组,x没有值
public void aa(int x,int ...nums) {
//可变参数你把他看成数组
int sum=0;
for(int i:nums){
sum+=i;
}
System.out.println(sum);
}
输出:
20
@Test
public void bb(){
List list=Arrays.asList("1","2","3");
System.out.println(list);
String arr[]={"1","2","3","4"};
list = Arrays.asList(arr);
System.out.println(list);
int nums[]={1,2,3,5};//这个细节一定要小心,注意可变参数类型,int nums[]是基本类型数组,这个数组就是一个对象,Arrays.asList(nums)的参数是对象集合。
list=Arrays.asList(nums);
System.out.println(list);
}
输出:
[1, 2, 3]
[1, 2, 3, 4]
[[I@1e63e3d]
5.枚举
1).枚举的作用
一些程序在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,jdk5以前采用自定义类来解决,jdk5以后可以直接采用枚举解决。
JDK5新增的enum关键字用于定义一个枚举类。
一个枚举也可以有构造函数、字段和方法。
2).枚举类具有如下特性:
枚举类也是一种特殊形式的Java类。
枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
与Java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。
枚举类也是可以实现接口或继承抽象类。
JDK5中扩展了swith语句,它除了可以接收int,byte,char,short外,还可以接收一个枚举类型。
若枚举类只有一个枚举值,则可以当作单态设计模式使用。
Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:
name()
ordinal()
valueof(Class enumClass,String name)
values()此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它用于遍历枚举的所有枚举值。
代码:
1>.
@Test
public void test() {
print(Grade.B);
}
public void print(Grade g) {
String value = g.getValue();
System.out.println(value);
}
// 如何定义枚举的构造函数、方法和字段,去封装更多的信息
enum Grade {
A("100-90"), B("89-80"), C("79-70"), D("69-60"), E("59-0");
private String value;// 封装每个对象对应的分数
private Grade(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}
输出:
89-80
2>.
@Test
public void test() {
print(Grade.B);
}
public void print(Grade g) {
String value = g.localValue();
System.out.println(value);
}
//带抽象方法的枚举
enum Grade {
A("100-90") {
public String localValue() {
return "优";
};
},
B("89-80") {
public String localValue() {
return "良";
};
},
C("79-70") {
public String localValue() {
return "一般";
};
},
D("69-60") {
public String localValue() {
return "差";
};
},
E("59-0") {
public String localValue() {
return "不及格";
};
};
private String value;// 封装每个对象对应的分数
private Grade(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
public abstract String localValue();
}
输出:
良
3>.测试枚举的常用方法
@Test
public void test2(){
System.out.println(Grade.C.name());
System.out.println(Grade.C.ordinal());
String str="B";
//Grade g=Grade.valueOf(Grade.class,str);
Grade g=Grade.valueOf(str);//str给出的值若无效则会报错
System.out.println(g);
Grade gs[]=Grade.values();
for(Grade g1:gs){
System.out.println(g1);
}
}
输出:
C
2
B
A
B
C
D
E
6.泛形(Generic)
1)泛形的作用
JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:
ArrayList list=new ArrayList();
list.add("abc");
Integer num=(Integer)list.get(0);//运行时会出错,但编码时发现不了
JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。示例。
List<String> list1=new ArrayList<String>();
list1.add("aaaa");
String s=list1.get(0);
2)掌握泛形的基本使用
掌握泛形集合的存取
3)泛形的几个注意事项
使用泛形时几个常见问题:
使用泛形时,泛形类型须为引用类型,不能是基本数据类型
ArrayList<Object> list=new ArrayList<String>();//错
ArrayList<String> list=new ArrayList<Object>();//错
ArrayList<String> list=new ArrayList();//对
ArrayList list=new ArrayList<String>();//对
用泛形时,如果两边都使用到泛形,两边必须要一样
注意:泛形是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
泛形的基本术语,以ArrayList<E>为例:<>念typeof
ArrayList<E>中的E称为类型参数变量
ArrayList<Integer>中的Integer称为实际类型参数
整个称为ArrayList<E>泛形类型
整个ArrayList<Integer>称为参数化的类型ParameterizedType
4)自定义泛形---泛形方法
Java程序中的普通方法、构造方法和静态方法中都可以使用泛形。
方法使用泛形前,必须对泛形进行声明,语法:<T>,T可以是任意字母,但通常必须要大写。<T>通常需要放在方法的返回值声明之前。例如:
public static <T> void doxx(T t);
练习:
编写一个泛形方法,实现指定位置上的数组元素的交换。(代码3)
编写一个泛形方法,接收一个任意数组,并颠倒数组中所有元素。(代码3)
注意:
只有对象类型才能作为泛形方法的实际参数。
在泛形中可以同时有多个类型,例如:
public static <K,V> V getValue(K key){return map.get(key);}
5)自定义泛形---泛形类和反射泛形
如果一个类多处都要用到同一个泛形,这时可以把泛形定义在类上(即类级别的泛形),语法格式如下:
public class GenericDao<T>{
private T field1;
public void save(T obj){}
public T getId(int id){}
}
注意,静态方法不能使用类定义的泛形,而应单独定义泛形。
泛形的典型应用:BaseDao和反射泛形
public BaseDao(){
Type type=this.getClass().getGenericSuperclass();
ParameterizedType pt=(ParameterizedType)type;
class=(Class)pt.getActualTypeArguments()[0];
}
6)
代码1:
package cn.itcast.generic;
//自定义带泛形的方法
public class Demo2 {
public void testa(){
a("aaa");
}
public <T> T a(T t){
return null;
}
public <T,E,K> void b(T t,E e,K k){
}
}
代码2:
package cn.itcast.generic;
//自定义类上的泛形
//类上面声明的泛形作用于整个类,静态方法上的泛形需要单独声明
public class Demo3<T,E,K> {
public void testa(){
}
public T a(T t){
return null;
}
public void b(T t,E e,K k){
}
public static <T> void c(T t){
}
}
代码3:
package cn.itcast.generic;
public class Demo4 {
// 编写一个泛形方法,实现指定位置上的数组元素的交换
public <T> void swap(T arr[], int pos1, int pos2) {
T temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
}
// 编写一个泛形方法,接收一个任意数组,并颠倒数组中所有元素。
public <T> void reverse1(T arr[]) {
int start = 0;
int end = arr.length - 1;
while (true) {
if (start >= end)
break;
T temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
public <T> void reverse2(T arr[]) {
int lenth = arr.length;
for (int i = 0; i < lenth / 2; i++) {
T temp = arr[i];
arr[i] = arr[lenth - i - 1];
arr[lenth - i - 1] = temp;
}
}
}
JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)的更多相关文章
- JDK5.0新特性 (Day_07)
JDK5.0新特性 目录 静态导入 自动装箱/拆箱 for-each循环 可变参数 枚举 JDK 5.0 新特性简介 JDK 5.0 的一个重要主题就是通过新增一些特性来简化开发,这些特性包括 ...
- JDK5.0新特性1
目录 静态导入 自动装箱/拆箱 for-each循环 可变参数 枚举 JDK 5.0 新特性简介 JDK 5.0 的一个重要主题就是通过新增一些特性来简化开发,这些特性包括: 静态导入 自动装箱/拆箱 ...
- Day07 jdk5.0新特性&Junit&反射
day07总结 今日内容 MyEclipse安装与使用 JUnit使用 泛型 1.5新特性 自动装箱拆箱 增强for 静态导入 可变参数方法 枚举 反射 MyEclipse安装与使用(yes) 安装M ...
- Javaweb学习笔记——(七)——————myexlipse基本使用、jdk5.0新特性及反射讲解
1.debug调试模式: *使用这种模式,调试程序(看到程序运行停止在这一行) -显示出来行号 -双击左边,出现一个圆点,表示设置了一个断点 *使用debug as方式,运行程序 -特使是否进入到调试 ...
- Java JDK5.0新特性
JDK5.0新特性 虽然JDK已经到了1.8 但是1.5(5.0)的变化是最大的 1. 增强for循环 foreach语句 foreach简化了迭代器 作用: 对存储对象的容器进行迭代 (数组, co ...
- JavaSE 学习笔记之Jdk5.0新特性(十九)
Jdk5.0新特性: Collection在jdk1.5以后,有了一个父接口Iterable,这个接口的出现的将iterator方法进行抽取,提高了扩展性. --------------------- ...
- Java基础和JDK5.0新特性
Java基础 JDK5.0新特性 PS: JDK:Java Development KitsJRE: Java Runtime EvironmentJRE = JVM + ClassLibary JV ...
- java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容
8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character ...
- java自动装箱拆箱总结
对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...
随机推荐
- PowerDesigner16逆向工程生成PDM列注释(My Sql5.0模版)
一.编辑当前DataBase 选择DataBase——>edit Current DBMS...弹出如下对话框: 如上图,先解释一下: 根据红颜色框从上往下解释一下. 第一个红框是对应的修改的 ...
- Servlet+JSP(三):第一个Web程序
Servlet+JSP(三):第一个Web程序在学习了服务器并成功安装后,我们知道当浏览器发送请求给服务器后,服务器会调用并执行对应的逻辑代码进行请求处理.逻辑代 码是由程序员自己编写然后放进服务器进 ...
- C#当中的out关键字(借鉴于CSDN)
一丶与ref关键字一样,out关键字也是按引用来传递的.out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数 ...
- 准备MPI编程环境——Visual Studio
准备 下载并安装Visual Studio 2017 下载并安装MPI (建议使用MSMPI,相对简单方便一点,可以从微软官网下载获得) 配置 新建空白项目 在该项目中新建源文件 右击项目-> ...
- [LUOGU]4932 浏览器
\(\_\_stdcall\)大佬出的题\(Orz\) 我们惊奇地发现,加入\(\_\_popcount(x)\)和\(\_\_popcount(y)\)的奇偶数性相同,那么\(\_\_popcoun ...
- 使用scrapy爬取的数据保存到CSV文件中,不使用命令
pipelines.py文件中 import codecs import csv # 保存到CSV文件中 class CsvPipeline(object): def __init__(self): ...
- C C++ POSIX 的一些 IO 操作
一些 C C++ POSIX 的 IO 操作总结 文件-内存之间 内存-内存之间 POSIX 有无缓冲的 IO 操作 对文件的操作,读文件至内存,从内存写至文件 // 读文件至内存buf中 void ...
- 一次vue-cli 2.x项目打包优化经历(优化xlsx插件)
一.分析各模块打包后大小 用vue-cli创建的项目,已经集成 webpack-bundle-analyzer.详见文件 build/webpack.prod.conf.js,代码如下: if (co ...
- cuda npp库旋转图片
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h&g ...
- time库
简介 返回系统当前时间戳(正常的生活时间) 返回格林威治时间戳对应的struct_time对象 本地时间的struct_time对象 当前时间戳对应的易读格式字符串时间(周几,月份,号数,时,分,秒, ...