Java5新特性

Java5的新特性

泛型(Generics)

泛型 : 为集合提供编译期间 (静态) 类型安全,且不须为大多数类型转换 (类型转换) (规范在 JSR 14)

由来

​ 早期的时候,我们使用Object来代表任意的类型。向上转型是没有任何问题的,但是在向下转型的时候其实隐含了类型转换的问题。也就是说这样的程序其实并不是安全的。所以Java在JDK5后引入了泛型,提高程序的安全性。

​ 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

泛型类

泛型接口

泛型方法

泛型高级(通配符)

​ ?       :任意类型,如果没有明确,那么就是Object以及任意的Java类了

​ ? extends E   :上边界(上界),向下限定,E及其子类

​ ? super E   :下边界(下界),向上限定,E极其父类

推荐链接:

Java 泛型 - 菜鸟 - 推荐

Java 泛型 - 推荐

Java 泛型 T,E,K,V,?,傻傻分不清? - 推荐

JavaSE学习笔记 - 泛型基础

Java学习之泛型及应用场景

Java全栈工程师开发之路

java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

java泛型(一)、泛型的基本介绍和使用

java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题

java泛型(三)、通配符的使用

枚举(Enumerations)

枚举: 以 enum 关键字创造出一种类型安全,有排序值的清单(如Day.MONDAY、 Day.TUESDAY 等);以前这只能透过非类型安全的恒定整数或自行撰写的类别来达成 (类型安全的枚举模式) (规范在JSR 201)

推荐链接:

Java 枚举(enum) - 菜鸟 - 必看

Java 枚举类 详解 - 必看

Java枚举(enum)详解:Java声明枚举类型、枚举(enum)类、EnumMap 与 EnumSet

Java 枚举(enum) 详解7种常见的用法

深入理解Java枚举类型(enum)

重新认识java(十) —- Enum(枚举类)

元数据/注解

元数据(Metadata): 也称作注解。让语言结构(像是类别和方法)能够用额外的数据标记,可以由元数据意识工具处理(规范在 JSR 175)

两种注解:1、在运行时通过反射机制处理的注解;2、在编译时处理的注解;

运行时处理注解

推荐链接:

Java注解

Java 注解(Annotation) | 菜鸟教程

Java自定义注解

深入理解Java注解类型(@Annotation)

一小时搞明白自定义注解(Annotation)

秒懂,Java 注解 (Annotation)你可以这样学 收费

Java中getClass( )和class()的联系和区别

编译时处理注解

见 Java SE 6 # Pluggable Annotation Processing API

自动装箱与拆箱

自动封装与解封装: 在基本的数据类型(如 int)和基本的的外覆类别 (如 Integer) 之间能够自动转换 (规范在 JSR 201)

推荐链接:

Java 中的自动装箱与拆箱 - 菜鸟

Java Number & Math 类 - 菜鸟

装箱与拆箱

可变参数函数

可变参数函数(Varargs):方法的最后一个参数现在可以用一个类型名称加上三个点宣告(如:void drawtext(String... lines));在调用代码中,类型中参数里任何的数字可以被使用,而它们再放在一个数组来传递给方法,或是其它的调用代码可以传递那个类型的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
1、如果我们在写方法的时候,参数个数不明确,就应该定义可变参数。
2、格式:
修饰符 返回值类型 方法名(数据类型… 变量名) {}
注意:
A:该变量名其实是一个数组名
B:如果一个方法有多个参数,并且有可变参数,可变参数必须在最后
*/

/**
* 需求:我要写一个求和的功能,到底是几个数据求和呢,我不太清楚,但是我知道在调用的时候我肯定就知道了
* 为了解决这个问题,Java就提供了一个东西:可变参数
*/
public class ArgsDemo {
public static void main(String[] args) {
int result = sum(10, 20, 30, 40);
System.out.println("result:" + result); // result:100

result = sum(10, 20, 30, 40, 50);
System.out.println("result:" + result); // result:150
}

public static int sum(int b, int... a) {
System.out.println(a); // [I@15db9742 由此可见,这里的 a 是数组名。
int s = b;
for (int x : a) {
s += x;
}
return s;
}
}

foreach循环/增强for

foreach 循环:把 for 循环的语法用特别的语法扩展。适用于数组或 Iterable,用于迭代每个成员,如基本的 Collection 类别 (规范在 JSR 201)

推荐链接:

Java 实例 - for 和 foreach循环使用 - 菜鸟

关于增强for循环的用法

静态导入

1、可以导入到方法级别的导入

2、格式:

​ import static 包名….类名.方法名;

3、注意事项:

​ A:方法必须是静态的

​ B:如果多个类下有同名的静态方法,就不好区分了,必须加前缀。所以一般我们并不使用静态导入,理解即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import static java.lang.System.err;
import static java.lang.System.out;
import java.io.IOException;
import java.io.PrintStream;

public class StaticImporter {
public static void main(String[] args) {
java.lang.System.out.println();
java.lang.System.err.println();
// 太复杂

System.out.println("");
System.err.println("");
// 还是复杂,有更简单的

// 引入import static
if (args.length < 2) {
err.println("Incorrect usage: java com.oreilly.tiger.ch08 [arg1] [arg2]");
return;
}
out.println("Good morning, " + args[0]);
out.println("Have a " + args[1] + " day!");
try {
writeError(System.out, "Error occurred.");
} catch (IOException e) {
e.printStackTrace();
}
}

public static void writeError(PrintStream err, String msg) throws IOException {
// Note that err in the parameter list overshadows the imported err
err.println(msg);
}
}

格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
* java.text.DateFormat
* java.text.SimpleDateFormat
* java.text.MessageFormat
* java.text.NumberFormat
* java.text.ChoiceFormat
* java.text.DecimalFormat
*/
public class FormatTester {

private static int MAY = 5;

public static void main(String[] args) {
formatter();
stringFormat();
messageFormat();
dateFormat();
printf();
}

public static void formatter() {
StringBuilder sb = new StringBuilder();
// Send all output to the Appendable object sb
Formatter formatter = new Formatter(sb, Locale.US);

// Explicit argument indices may be used to re-order output.
formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
sb.append("\n");
// -> " d c b a"
// Optional locale as the first argument can be used to get
// locale-specific formatting of numbers. The precision and width can be
// given to round and align the value.
formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
sb.append("\n");
// -> "e = +2,7183"
// The '(' numeric flag may be used to format negative numbers with
// parentheses rather than a minus sign. Group separators are
// automatically inserted.
formatter.format("Amount gained or lost since last statement: $ %(,.2f", 6217.58);
// -> "Amount gained or lost since last statement: $ (6,217.58)"

System.out.println(sb);
}

public static void stringFormat() {
// Format a string containing a date.
Calendar c = new GregorianCalendar(1995, MAY, 23);
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
// -> s == "Duke's Birthday: May 23, 1995"
System.out.println(s);
}

public static void messageFormat() {
String msg = "欢迎光临,当前({0})等待的业务受理的顾客有{1}位,请排号办理业务!";
MessageFormat mf = new MessageFormat(msg);
String fmsg = mf.format(new Object[] { new Date(), 35 });
System.out.println(fmsg);
}

public static void dateFormat() {
String str = "2010-1-10 17:39:21";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
System.out.println(format.format(format.parse(str)));
} catch (ParseException e) {
e.printStackTrace();
}
}

public static void printf() {
// printf
String filename = "this is a file";
try {
File file = new File(filename);
FileReader fileReader = new FileReader(file);
BufferedReader reader = new BufferedReader(fileReader);
String line;
int i = 1;
while ((line = reader.readLine()) != null) {
System.out.printf("Line %d: %s%n", i++, line);
}
} catch (Exception e) {
System.err.printf("Unable to open file named '%s': %s", filename, e.getMessage());
}
}

}

Arrays工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* public static <T> List<T> asList(T... a):把数组转成集合
*
* 注意事项:
* 虽然可以把数组转成集合,但是集合的长度不能改变。
*/
public class ArraysDemo {
public static void main(String[] args) {
// 定义一个数组
// String[] strArray = { "hello", "world", "java" };
// List<String> list = Arrays.asList(strArray);
List<String> list = Arrays.asList("hello", "world", "java");

// list.add("javaee"); // UnsupportedOperationException
// list.remove(1); // UnsupportedOperationException

list.set(1, "javaee");

for (String s : list) {
System.out.println(s); // hello \n javaee \n java \n
}
}
}