(ps:本来只总结在一个贴子里面的,但是发现帖子要求的字符数是10000,删了好多发现帖子长度还是不符合系统要求,再删发现很多内容讲得很仔细很到位,删了可惜,故分成两贴子)
之前看毕姥爷是视频,总会时不时听到关于jdk1.4和jdk1.5的一些差别,毕姥爷是碰到差别的时候就讲一讲.看张老师的视频也提到之前黑马学长找工作过程中说出jdk1.4和jdk1.5的区别以及jdk1.5和jdk1.6的区别.我找了些资料,关于jdk1.4、1.5和1.6的差别的系统的一个总结,资料如下,希望对大家学习java以及以后面试找工作有所帮助.
jdk1.4和jdk1.5的区别:
范型和foreach是亮点
1. 泛型
2 自动装箱/拆箱
3 for-each
4 static import
5 变长参数
1. 泛型 1.4之前 java util包中容器类,装的是Object对象,你要装特定的类型可以,但要强制转换,这可能导致运行时错误.
例:原来ArrayList list=new ArrayList();
list.add(new Integer(3));
list.add(new Integer(4));
int i=((Integer)(list.get(0))).parseInt();
很麻烦
现在ArrayList <Integer> list=new ArrayList <Integer> ();
list.add(new Integer(3));
list.add(new Integer(4));
int i=list.get(0).parseInt();
不用Cast,运行时错误变为编译时错误,这是进步.
类似与C++中的摸板templete.但机理不同.
2 自动装箱/拆箱
还是刚才例子
最后一句可改为
int i=list.get(0);
原始类型与对应的包装类不用显式转换,方便
3 for-each
循环的增强
int a[]={........};//初始化,略
for(int i:a)
{
......
}
不用以前的i=0;i <a.length;i++
4 static import
以前调Java.math
Math.sqrt();
现在 static import java.lang.Math.sqrt;
再 sqrt();
相当于你自己类里有这个方法
5 变长参数
int sum(int ...intlist)
{
int i,sum;
sum=0;
for(int i=0;i <intlist.length;i++)
{
sum+=list;
}
return sum;
}
有任意个参数,把他看作数组
没多大区别,只要你注意别用那些过时的方法就行,若是新版本加的或有改变的方法,docs里会说的,在方法解释下面
下面作些补充
增强的for循环
为了迭代集合和数组,增强的for循环提供了一个简单、兼容的语法。有两点值得一提:
Init表达式
在循环中,初始化表达式只计算一次。这意味着您通常可以移除一个变量声明。在这个例子中,我们必须创建一个整型数组来保存computeNumbers()的结果,以防止每一次循环都重新计算该方法。您可以看到,下面的代码要比上面的代码整洁一些,并且没有泄露变量numbers:
未增强的For:
int sum = 0;
Integer[] numbers = computeNumbers();
for (int i=0; i < numbers.length ; i++)
sum += numbers;
增强后的For:
int sum = 0;
for ( int number: computeNumbers() )
sum += number;
局限性
有时需要在迭代期间访问迭代器或下标,看起来增强的for循环应该允许该操作,但事实上不是这样,请看下面的例子:
for (int i=0; i < numbers.length ; i++) {
if (i != 0) System.out.print(",");
System.out.print(numbers);
}
我们希望将数组中的值打印为一个用逗号分隔的清单。我们需要知道目前是否是第一项,以便确定是否应该打印逗号。使用增强的for循环是无法获知这种信息的。我们需要自己保留一个下标或一个布尔值来指示是否经过了第一项。 这是另一个例子:
for (Iterator<integer> it = n.iterator() ; it.hasNext() ; )
if (it.next() < 0)
it.remove();
在此例中,我们想从整数集合中删除负数项。为此,需要对迭代器调用一个方法,但是当使用增强的for 循环时,迭代器对我们来说是看不到的。因此,我们只能使用Java 5之前版本的迭代方法。 顺便说一下,这里需要注意的是,由于Iterator是泛型,所以其声明是Iterator<Integer>。许多人都忘记了这一点而使用了Iterator的原始格式。
枚举
enum非常像public static final int声明,后者作为枚举值已经使用了很多年。对int所做的最大也是最明显的改进是类型安全——您不能错误地用枚举的一种类型代替另一种类型,这一点和int不同,所有的int对编译器来说都是一样的。除去极少数例外的情况,通常都应该用enum实例替换全部的枚举风格的int结构。
枚举提供了一些附加的特性。EnumMap和EnumSet这两个实用类是专门为枚举优化的标准集合实现。如果知道集合只包含枚举类型,那么应该使用这些专门的集合来代替HashMap或HashSet。
大部分情况下,可以使用enum对代码中的所有public static final int做插入替换。它们是可比的,并且可以静态导入,所以对它们的引用看起来是等同的,即使是对于内部类(或内部枚举类型)。注意,比较枚举类型的时候,声明它们的指令表明了它们的顺序值。
“隐藏的”静态方法
两个静态方法出现在所有枚举类型声明中。因为它们是枚举子类上的静态方法,而不是Enum本身的方法,所以它们在java.lang.Enum的javadoc中没有出现。
第一个是values(),返回一个枚举类型所有可能值的数组。
第二个是valueOf(),为提供的字符串返回一个枚举类型,该枚举类型必须精确地匹配源代码声明。
方法
关于枚举类型,我们最喜欢的一个方面是它可以有方法。过去您可能需要编写一些代码,对public static final int进行转换,把它从数据库类型转换为JDBC URL。而现在则可以让枚举类型本身带一个整理代码的方法。下面就是一个例子,包括DatabaseType枚举类型的抽象方法以及每个枚举实例中提供的实现:
public enum DatabaseType {
ORACLE {
public String getJdbcUrl() {...}
},
MYSQL {
public String getJdbcUrl() {...}
};
public abstract String getJdbcUrl();
}
现在枚举类型可以直接提供它的实用方法。例如:
DatabaseType dbType = ...;
String jdbcURL = dbType.getJdbcUrl();
要获取URL,必须预先知道该实用方法在哪里。
可变参数(Vararg)
正确地使用可变参数确实可以清理一些垃圾代码。典型的例子是一个带有可变的String参数个数的log方法:
Log.log(String code)
Log.log(String code, String arg)
Log.log(String code, String arg1, String arg2)
Log.log(String code, String[] args)
当讨论可变参数时,比较有趣的是,如果用新的可变参数替换前四个例子,将是兼容的:
Log.log(String code, String... args)
所有的可变参数都是源兼容的——那就是说,如果重新编译log()方法的所有调用程序,可以直接替换全部的四个方法。然而,如果需要向后的二进制兼容性,那么就需要舍去前三个方法。只有最后那个带一个字符串数组参数的方法等效于可变参数版本,因此可以被可变参数版本替换。
类型强制转换
如果希望调用程序了解应该使用哪种类型的参数,那么应该避免用可变参数进行类型强制转换。看下面这个例子,第一项希望是String,第二项希望是Exception:
Log.log(Object... objects) {
String message = (String)objects[0];
if (objects.length > 1) {
Exception e = (Exception)objects[1];
// Do something with the exception
}
}
方法签名应该如下所示,相应的可变参数分别使用String和Exception声明:
Log.log(String message, Exception e, Object... objects) {...}
不要使用可变参数破坏类型系统。需要强类型化时才可以使用它。对于这个规则,PrintStream.printf()是一个有趣的例外:它提供类型信息作为自己的第一个参数,以便稍后可以接受那些类型。
|
|