——- android培训、java培训、期待与您交流! ———-
JDK5新特性
自动拆装箱
自动装箱:把基本类型转换为包装类类型
自动拆箱:把包装类类型转换为基本类型
public class IntegerDemo {
public static void main(String[] args) {
// 定义了一个int类型的包装类类型变量i
// Integer i = new Integer(100);
Integer ii = 100;
ii += 200;
System.out.println("ii:" + ii);
// 通过反编译后的代码
// Integer ii = Integer.valueOf(100); //自动装箱
// ii = Integer.valueOf(ii.intValue() + 200); //自动拆箱,再自动装箱
// System.out.println((new StringBuilder("ii:")).append(ii).toString());
}
}
}
泛型
泛型是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
格式:
<数据类型>
此处的数据类型只能是引用类型
好处
- A:把运行时期的问题提前到了编译期间
- B:避免了强制类型转换
- C:优化了程序设计,解决了黄色警告线
泛型类
/*
* 泛型类:把泛型定义在类上
*/
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
测试
/*
* 泛型类的测试
*/
public class ObjectToolDemo {
public static void main(String[] args) {
ObjectTool<String> ot = new ObjectTool<String>();
// ot.setObj(new Integer(27)); //这个时候编译期间就过不去
ot.setObj(new String("李延旭"));
String s = ot.getObj();
System.out.println("姓名是:" + s);
ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
// ot2.setObj(new String("周杰伦"));//这个时候编译期间就过不去
ot2.setObj(new Integer(27));
Integer i = ot2.getObj();
System.out.println("年龄是:" + i);
}
}
泛型方法
/*
* 泛型方法:把泛型定义在方法上
*/
public class ObjectTool {
public <T> void show(T t) {
System.out.println(t);
}
}
测试
public class ObjectToolDemo {
public static void main(String[] args) {
// 定义泛型方法后,方法中可以传入任意类型的参数
ObjectTool ot = new ObjectTool();
ot.show("hello");
ot.show(100);
ot.show(true);
}
}
泛型接口
/*
* 泛型接口:把泛型定义在接口上
*/
public interface Inter<T> {
public abstract void show(T t);
}
实现类
//实现类在实现接口的时候
//第一种情况:已经知道该是什么类型的了
//public class InterImpl implements Inter<String> {
//
// @Override
// public void show(String t) {
// System.out.println(t);
// }
// }
//第二种情况:还不知道是什么类型的
public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
测试
public class InterDemo {
public static void main(String[] args) {
// 第一种情况的测试
// Inter<String> i = new InterImpl();
// i.show("hello");
// // 第二种情况的测试
Inter<String> i = new InterImpl<String>();
i.show("hello");
Inter<Integer> ii = new InterImpl<Integer>();
ii.show(100);
}
}
泛型通配符
import java.util.ArrayList;
import java.util.Collection;
/*
* 泛型高级(通配符)
* ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
* ? extends E:向下限定,E及其子类
* ? super E:向上限定,E极其父类
*/
public class GenericDemo {
public static void main(String[] args) {
// 泛型如果明确的写的时候,前后必须一致
Collection<Object> c1 = new ArrayList<Object>();
// Collection<Object> c2 = new ArrayList<Animal>();
// Collection<Object> c3 = new ArrayList<Dog>();
// Collection<Object> c4 = new ArrayList<Cat>();
// ?表示任意的类型都是可以的
Collection<?> c5 = new ArrayList<Object>();
Collection<?> c6 = new ArrayList<Animal>();
Collection<?> c7 = new ArrayList<Dog>();
Collection<?> c8 = new ArrayList<Cat>();
// ? extends E:向下限定,E及其子类
// Collection<? extends Animal> c9 = new ArrayList<Object>();
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>();
// ? super E:向上限定,E极其父类
Collection<? super Animal> c13 = new ArrayList<Object>();
Collection<? super Animal> c14 = new ArrayList<Animal>();
// Collection<? super Animal> c15 = new ArrayList<Dog>();
// Collection<? super Animal> c16 = new ArrayList<Cat>();
}
}
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
增强for
增强for:是for循环的一种,其实是用来替代迭代器的。
格式:
for(元素数据类型 变量 : 数组或者Collection集合) {
使用变量即可,该变量就是元素
}
好处:简化了数组和集合的遍历。
弊端: 增强for的目标不能为null。
解决方法:对增强for的目标先进行不为null的判断,然后再使用。
import java.util.ArrayList;
import java.util.List;
public class ForDemo {
public static void main(String[] args) {
// 定义一个int数组
int[] arr = { 1, 2, 3, 4, 5 };
for (int x = 0; x < arr.length; x++) {
System.out.println(arr[x]);
}
System.out.println("---------------");
// 增强for
for (int x : arr) {
System.out.println(x);
}
System.out.println("---------------");
// 定义一个字符串数组
String[] strArray = { "刘德华", "郭富城", "黎明", "张学友" };
// 增强for
for (String s : strArray) {
System.out.println(s);
}
System.out.println("---------------");
// 定义一个集合
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
// 增强for
for (String s : array) {
System.out.println(s);
}
System.out.println("---------------");
List<String> list = null;
// NullPointerException
// 这个s是我们从list里面获取出来的,在获取前,它肯定还要做一个判断
if (list != null) {
for (String s : list) {
System.out.println(s);
}
}
}
}
静态导入
普通导入只能导入一个类,静态导入可以直接导入到方法的级别
格式: import static 包名…类名.方法名;
import static java.lang.Math.abs;
import static java.lang.Math.pow;
import static java.lang.Math.max;
//错误
//import static java.util.ArrayList.add;
public class StaticImportDemo {
public static void main(String[] args) {
//有同名方法,需要加前缀使用
System.out.println(java.lang.Math.abs(-100));
System.out.println(pow(2, 3));
System.out.println(max(20, 30));
}
public static void abs(String s){
System.out.println(s);
}
}
注意:
方法必须是静态的,如果有多个同名静态方法,容易混淆,这个时候要使用,必须加前缀,由此可见,意义不大,一般不用。
可变参数
定义方法的时候不知道该定义多少个参数,就可以使用可变参数
格式:
修饰符 返回值类型 方法名(数据类型… 变量名){
}
注意
这里的变量其实是一个数组
如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
public class ArgsDemo {
public static void main(String[] args) {
result = sum(a, b, c, d, 40);
System.out.println("result:" + result);
result = sum(a, b, c, d, 40, 50);
System.out.println("result:" + result);
}
public static int sum(int... a) {
int s = 0;
for(int x : a){
s +=x;
}
return s;
}
}
枚举
将变量的值一一列举出来,变量的值只限于列举出来的值得范围,举例:一周只有七天,一分钟只有60秒。
单例模式是一个类只有一个实例,那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例,这就是枚举类。
自定义枚举类
public class DirectionDemo {
public static void main(String[] args) {
Direction d = Direction.FRONT;
System.out.println(d); // FRONT
// public String toString()返回枚举常量的名称,它包含在声明中。
System.out.println("-------------");
Direction2 d2 = Direction2.FRONT;
System.out.println(d2);
System.out.println(d2.getName());
System.out.println("-------------");
Direction3 d3 = Direction3.FRONT;
System.out.println(d3);
System.out.println(d3.getName());
d3.show();
System.out.println("--------------");
Direction3 dd = Direction3.FRONT;
dd = Direction3.LEFT;
switch (dd) {
case FRONT:
System.out.println("你选择了前");
break;
case BEHIND:
System.out.println("你选择了后");
break;
case LEFT:
System.out.println("你选择了左");
break;
case RIGHT:
System.out.println("你选择了右");
break;
}
}
}
通过JDK5来定义枚举类
public enum Direction3 {
FRONT("前") {
@Override
public void show() {
System.out.println("前");
}
},
BEHIND("后") {
@Override
public void show() {
System.out.println("后");
}
},
LEFT("左") {
@Override
public void show() {
System.out.println("左");
}
},
RIGHT("右") {
@Override
public void show() {
System.out.println("右");
}
};
private String name;
private Direction3(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract void show();
}
枚举中的方法
写一个简单枚举类
public enum Direction2 {
FRONT("前"), BEHIND("后"), LEFT("左"), RIGHT("右");
private String name;
private Direction2(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
测试类
public class EnumMethodDemo {
public static void main(String[] args) {
// int compareTo(E o):比较此枚举与指定对象的顺序
Direction2 d21 = Direction2.FRONT;
Direction2 d22 = Direction2.BEHIND;
Direction2 d23 = Direction2.LEFT;
Direction2 d24 = Direction2.RIGHT;
System.out.println(d21.compareTo(d21));
System.out.println(d21.compareTo(d24));
System.out.println(d24.compareTo(d21));
System.out.println("---------------");
// String name():返回枚举常量的名称
System.out.println(d21.name());
System.out.println(d22.name());
System.out.println(d23.name());
System.out.println(d24.name());
System.out.println("--------------");
// int ordinal():返回枚举常量的序数
System.out.println(d21.ordinal());
System.out.println(d22.ordinal());
System.out.println(d23.ordinal());
System.out.println(d24.ordinal());
System.out.println("--------------");
// String toString():返回枚举常量的名称
System.out.println(d21.toString());
System.out.println(d22.toString());
System.out.println(d23.toString());
System.out.println(d24.toString());
System.out.println("--------------");
// <T> T valueOf(Class<T> type,String name):返回带指定名称的指定枚举类型的枚举常量
Direction2 d = Enum.valueOf(Direction2.class, "FRONT");
System.out.println(d.getName());
System.out.println("----------------");
// values()
// 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便
Direction2[] dirs = Direction2.values();
for (Direction2 d2 : dirs) {
System.out.println(d2);
System.out.println(d2.getName());
}
}
}
注意事项
- 定义枚举类要用关键字enum
- 所有枚举类都是Enum的子类
- 枚举类的第一行上必须枚举项,最有一个枚举项后面的分号可以省略。但如果枚举项后面有其他的代码,分号就不能省略,建议永远不要省略。
- 枚举类可以有构造器,但必须是private修饰的,默认也是private,枚举 项的用法比较特殊:枚举(“”);
- 枚举类可以有构造方法,但是枚举项必须重写该方法。
JDK7新特性
二进制字面量
JDK7可以用二进制来表示整数,语法很简单,只需要在二进制数值前面加上0b或者0B 。
public class Demo {
public static void main(String[] args) {
// 二进制字面量
int x = 0b100101;
System.out.println(x);
}
数字字面量可以出现下划线
为了增强对数值的阅读性,就像我们经常把数据用逗号分隔一样,JDK7提供了_用来对数据进行分割。
public class Demo {
public static void main(String[] args) {
// 数字字面量可以出现下划线
int y = 1_1123_1000;
// 不能出现在进制标识和数值之间
int z = 0x111_222;
// 不能出现在数值开头和结尾
int a = 0x11_22;
// 不能出现在小数点旁边
double d = 12.3_4;
}
switch语句可以用字符串
import java.util.Scanner;
class SwitchTest3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
//录入数据
System.out.println("请输入你要判断的字符串:");
String s = sc.nextLine();
switch(s) {
case "hello":
System.out.println("你输入的是hello");
break;
case "world":
System.out.println("你输入的是world");
break;
case "java":
System.out.println("你输入的是java");
break;
default:
System.out.println("没有找到你输入的数据");
//break;
}
}
}
泛型简化
ArrayList<String> array = new ArrayList<>();
建议不那么写,最好一直写上。
异常的多个catch合并
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
method();
}
public static void method() {
// try-with-resources 语句
// try(必须是java.lang.AutoCloseable的子类对象){…}
try {
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
// JDK7改进版
try (FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");) {
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结
JDK7的新特性现在还不算太常见,了解即可,而JDK6的改进基本可以忽略不计,所以我们现在用的大部分是JDK5的新特性,JDK5对很多方面都有很大的改进,比如增强for,泛型等等。对于JDK5,我们要重点掌握。