以下两文:
http://heaven-arch.iteye.com/blog/165452
http://www.iteye.com/topic/489394
总结如下:
1.泛型(Generic) 2.增强for循环(For-Each循环) 3.自动装箱与拆箱(Autoboxing/unboxing) 4.静态导入(static import) 5.格式化打印(formatted print) 6.枚举(Enum) 7.可变参数(varargs)8.注解annotation
面试的时候面试官问我jdk1.5的新特性,居然只回答上两个(泛型,增强for循环),回来一查,其实都接触过,而且好几个特性自己还经常用。
下面就总结一下:1.泛型(Generic) 2.增强for循环(For-Each循环) 3.自动装箱与拆箱(Autoboxing/unboxing) 4.静态导入(static import) 5.格式化打印(formatted print) 6.枚举(Enum) 7.可变参数(varargs)
1、泛型(Generic)
可以在编译的时候检测出类型错误,编译后和没有使用泛型的效果是相同的,但是使用泛型可以让你在编译时就发现错误,例如:
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Iterator;
- public class GenericTest {
- public static void main(String[] args) {
- Collection c = new ArrayList();
- c.add(new Integer(1));
- c.add("123");
- for(Iterator i=c.iterator();i.hasNext();){
- String s = (String) i.next();
- System.out.println(s);
- }
- }
- }
- 运行结果:
- Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
- at GenericTest.main(GenericTest.java:12)
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class GenericTest { public static void main(String[] args) { Collection c = new ArrayList(); c.add(new Integer(1)); c.add("123"); for(Iterator i=c.iterator();i.hasNext();){ String s = (String) i.next(); System.out.println(s); } } } 运行结果: Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at GenericTest.main(GenericTest.java:12)
Collection应该只存放String对象,但是我们“不小心”添加了一个Integer类型的对象,编译正常进行,程序在运行时才发现错误。
下面是使用了泛型后的程序
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Iterator;
- public class GenericTest {
- public static void main(String[] args) {
- Collection<String> c = new ArrayList<String>();
- c.add(new Integer(1));
- c.add("123");
- for(Iterator<String> i=c.iterator();i.hasNext();){
- String s = i.next();
- System.out.println(s);
- }
- }
- }
- 运行结果
- D:\test>javac GenericTest.java
- GenericTest.java:8: 无法将 java.util.Collection<java.lang.String> 中的 add(java.lang.String) 应用于 (java.lang.Integer)
- c.add(new Integer(1));
- ^
- 1 错误
- D:\test>
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class GenericTest { public static void main(String[] args) { Collection<String> c = new ArrayList<String>(); c.add(new Integer(1)); c.add("123"); for(Iterator<String> i=c.iterator();i.hasNext();){ String s = i.next(); System.out.println(s); } } } 运行结果 D:\test>javac GenericTest.java GenericTest.java:8: 无法将 java.util.Collection<java.lang.String> 中的 add(java.lang.String) 应用于 (java.lang.Integer) c.add(new Integer(1)); ^ 1 错误 D:\test>
使用了泛型之后在编译时就发现了错误,可以增强程序的健壮性,而其i.next();也不用使用强制类型转换了。
2、增强for循环(For-Each)
For-Each的内部是用Iterator实现的,但是使用起来更简单,例如使用For-Each实现1-2如下
- import java.util.ArrayList;
- import java.util.Collection;
- public class GenericTest {
- public static void main(String[] args) {
- Collection<String> c = new ArrayList<String>();
- c.add("aa");
- c.add("bb");
- for(String s:c){
- System.out.println(s);
- }
- }
- }
- 运行结果:
- aa
- bb
import java.util.ArrayList; import java.util.Collection; public class GenericTest { public static void main(String[] args) { Collection<String> c = new ArrayList<String>(); c.add("aa"); c.add("bb"); for(String s:c){ System.out.println(s); } } } 运行结果: aa bb
比Integer方便多了吧?可以使程序员更加注重逻辑,而不是代码本身。
3、自动装箱拆箱(Autoboxing/unboxing)
- Integer i = new Integer(2);
- //i自动拆箱为int类型
- System.out.println(i==2);
- //3自动装箱为Integer类型
- System.out.println(i.equals(3));
Integer i = new Integer(2); //i自动拆箱为int类型 System.out.println(i==2); //3自动装箱为Integer类型 System.out.println(i.equals(3));
4、静态导入(static import)
- //静态导入Math的random方法
- import static java.lang.Math.random;
- public class StaticImportTest {
- public static void main(String[] args){
- //类中生成随机数数可以直接使用静态引入的random方法了,而不用Math.random()这样调用了
- System.out.println(random());
- }
- }
//静态导入Math的random方法 import static java.lang.Math.random; public class StaticImportTest { public static void main(String[] args){ //类中生成随机数数可以直接使用静态引入的random方法了,而不用Math.random()这样调用了 System.out.println(random()); } }
5、格式化打印(formatted print)
C语言中printf()风格的格式化输出。
这里只举一个thinking in java的一个例子:
- public class SimpleFormat {
- public static void main(String[] args) {
- int x = 5;
- double y = 5.332542;
- //The old way
- System.out.println("Row 1: ["+x+" "+y+"]");
- //The new way
- System.out.format("Row 1: [%d %f]\n", x,y);
- //or
- System.out.printf("Row 1: [%d %f]\n", x, y);
- }
- }
- 运行结果:
- Row 1: [5 5.332542]
- Row 1: [5 5.332542]
- Row 1: [5 5.332542]
public class SimpleFormat { public static void main(String[] args) { int x = 5; double y = 5.332542; //The old way System.out.println("Row 1: ["+x+" "+y+"]"); //The new way System.out.format("Row 1: [%d %f]\n", x,y); //or System.out.printf("Row 1: [%d %f]\n", x, y); } } 运行结果: Row 1: [5 5.332542] Row 1: [5 5.332542] Row 1: [5 5.332542]
可以看到,format和printf是等价的,他们只需要一个简单的格式化字符串,加上一串参数即可,每个参数对应一个格式修饰符
6、枚举(Enum)
当每一类型可取值范围是有限的时候,可以使用枚举,例如每个学生登记只能用ABCD表示,如果直接用E的话,那么编译不会出错,但是却不符合输入要求,而使用枚举增加程序的易读性和健壮性?
- public class GradeTest {
- public static void main(String[] args) {
- Student stu = new Student();
- stu.setName("wasw100");
- stu.setGrade(Grade.A);
- //输出学生信息
- System.out.println(stu);
- }
- }
- /**
- * 枚举:Grader 学生考试等级
- * @author wasw100
- */
- enum Grade{
- A,B,C,D
- }
- class Student {
- private String name;
- private Grade grade;
- //重写toString()方法
- public String toString(){
- return "name:+"+name+"\ngrader:"+grade;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Grade getGrade() {
- return grade;
- }
- public void setGrade(Grade grade) {
- this.grade = grade;
- }
- }
public class GradeTest {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("wasw100");
stu.setGrade(Grade.A);
//输出学生信息
System.out.println(stu);
}
}
/**
* 枚举:Grader 学生考试等级
* @author wasw100
*/
enum Grade{
A,B,C,D
}
class Student {
private String name;
private Grade grade;
//重写toString()方法
public String toString(){
return "name:+"+name+"\ngrader:"+grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
}
7、可变长参数(varargs)
方法的参数是不固定的我们一般会使用重载或者使用数组参数。重载需要些更多写更多的方法,数组需要在使用时先声明。
可能参数是一个不错的解决方案。
下面是网上一个 唐僧 给 悟空 将佛经的例子
- public class VarargsTest {
- public void speak(String name, Object... arguments) {
- System.out.print(name+": ");
- for (Object object : arguments) {
- System.out.print(object);
- }
- System.out.println();
- }
- public static void main(String[] args) {
- VarargsTest vt = new VarargsTest();
- vt.speak("悟空", "人和妖精都是妈生的,");
- vt.speak("悟空", "不同的人是人他妈生的,", "妖是妖他妈生的,");
- }
- }
- 运行结果:
- 悟空: 人和妖精都是妈生的,
- 悟空: 不同的人是人他妈生的,妖是妖他妈生的,
public class VarargsTest {
public void speak(String name, Object... arguments) {
System.out.print(name+": ");
for (Object object : arguments) {
System.out.print(object);
}
System.out.println();
}
public static void main(String[] args) {
VarargsTest vt = new VarargsTest();
vt.speak("悟空", "人和妖精都是妈生的,");
vt.speak("悟空", "不同的人是人他妈生的,", "妖是妖他妈生的,");
}
}
运行结果:
悟空: 人和妖精都是妈生的,
悟空: 不同的人是人他妈生的,妖是妖他妈生的,
可变长参数只能作为最后一个参数。