java5 新特性
2015-10-21 23:19
190 查看
1.静态导入方法
Java代码
package com.java.new_features_jdk5;
/**
*
* 一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com.....ClassName.*;
* 这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。
* 然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
* 这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(...);就可以将其写入一个静态方法print(...),在使用时直接print(...)就可以了。
* 但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便。
* @author yuahan
*
*/
public class _Static_Import {
public static void main(String[] args) {
}
}
2.新增加的for循环
Java代码
package com.java.new_features_jdk5;
import java.util.ArrayList;
import java.util.List;
/**
* 增强的for循环,可以使用在数组和容器中
* @author yuahan
*
*/
public class _For {
@SuppressWarnings("serial")
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,9,10};
for(int num : array){
System.out.print(num + " ");
}
System.out.println();
List<Integer> list = new ArrayList<Integer>(){{
this.add(1);
this.add(2);
this.add(3);
this.add(4);
this.add(5);
this.add(6);
this.add(7);
this.add(8);
this.add(9);
this.add(10);
}};
for(int num : list){
System.out.print(num + " ");
}
}
}
3.枚举 Enum
Java代码
package com.java.new_features_jdk5;
/**
*
* 你可以将枚举类型视为特殊的类,因此几乎可以像创建普通类那样创建枚举。
* 枚举类型有附加的特性,有EnumMap和EnumSet两个类。实例化方法中都需要传入枚举类型的类类型,如:
* EnumSet<_Enum> set = EnumSet.noneOf(_Enum.class);
EnumMap<_Enum,String> map = new EnumMap<_Enum,String>(_Enum.class);
枚举可以有自己的构造方法,不过构造方法只能私有,这样外部是不能构造出新的枚举中的实例,而只是调用其中的实例。
* @author yuahan
*
*/
public enum _Enum {
Better(90),
Good(80),
Ok(70),
Bad(60),
Worse;
private int value;
private _Enum() {
this.value = 30;
}
private _Enum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public static _Enum[] getEnumValues(){
return _Enum.values();
}
public static void _ValuesOf(){
// _Enum test = _Enum.valueOf("test");//error
// System.out.println(test);
_Enum Better = _Enum.valueOf("Better");
System.out.println(Better);
}
public static void main(String[] args) {
for(_Enum mark : _Enum.getEnumValues()){
switch(mark){
case Better:
System.out.println(_Enum.Better);
break;
case Good:
System.out.println(_Enum.Good);
break;
case Ok:
System.out.println(_Enum.Ok);
break;
case Bad:
System.out.println(_Enum.Bad);
break;
case Worse:
System.out.println(_Enum.Worse);
break;
}
}
_Enum._ValuesOf();
System.out.println(_Enum.Better.getValue());
}
}
4.反射 Reflect
Java代码
package com.java.new_features_jdk5;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
/**
* Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。
* Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性
* JavaDoc 中对每个类和其中的方法有非常详细介绍。主要有:
* Class ------- java.lang
* Package ------- java.lang
*
* Array
* Field
* Method
* Modifier
* Constructor
* @author yuahan
*
*/
public class _Reflect {
private int id;
private String name;
private String[] hobbies;
public _Reflect(){}
public _Reflect(int id){
this.id = id;
}
public _Reflect(int id, String name, String[] hobbies) {
super();
this.id = id;
this.name = name;
this.hobbies = hobbies;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public static void main(String[] args) throws Exception{
//---------------------------------basic---------------------------------
System.out.println(_Reflect.class.getSimpleName());
System.out.println(_Reflect.class.getName());
System.out.println(_Reflect.class.getPackage());
System.out.println(_Reflect.class.getSuperclass().getName());
System.out.println(int[].class.getName());
System.out.println(_Reflect[].class.getName());
// //--------------------------------- Method ---------------------------------
Method[] methods = _Reflect.class.getMethods();
for(Method method : methods){
System.out.println(method + ": " +method.getDeclaringClass().getName());
}
// //--------------------------------- isXXX ---------------------------------
System.out.println(Comparable.class.isInterface());
System.out.println(int.class.isPrimitive());
System.out.println(int[].class.isArray());
// //--------------------------------- Modifier 修饰符 ---------------------------------
System.out.println(Modifier.isPublic(_Reflect.class.getModifiers()));
Class<?>[] classes = null;
System.out.println(Modifier.isPublic(_Reflect.class.getMethod("getId",classes).getModifiers()));
//isAssignableFrom isInstance
System.out.println(Number.class.isAssignableFrom(Integer.class));
System.out.println(Number.class.isInstance(1));
//---------------------------------Field---------------------------------
_Reflect _Reflect = new _Reflect();
System.out.println(_Reflect.getId());
System.out.println(_Reflect.getName());
System.out.println(Arrays.toString(_Reflect.getHobbies()));
Field[] fields = _Reflect.class.getDeclaredFields();
for(Field field : fields){
if(field.getType() == int.class){
field.setAccessible(true);
field.setInt(_Reflect, 1);
}else if(field.getType() == String.class){
field.setAccessible(true);
field.set(_Reflect, "1");
}else if(field.getType() == String[].class){
field.setAccessible(true);
field.set(_Reflect, new String[]{"1","1"});
}
}
System.out.println(_Reflect.getId());
System.out.println(_Reflect.getName());
System.out.println(Arrays.toString(_Reflect.getHobbies()));
// //---------------------------------new instance---------------------------------
Constructor<_Reflect> constructor = _Reflect.class.getConstructor(new Class[]{int.class,String.class,String[].class});
_Reflect _reflect = constructor.newInstance(new Object[]{1,"1",new String[]{"1","1"}});
System.out.println(_reflect.getId());
System.out.println(_reflect.getName());
System.out.println(Arrays.toString(_Reflect.getHobbies()));
Class<?> clazz = Class.forName("com.java.new_features_jdk5._Reflect");
_Reflect clazzes = (_Reflect)clazz.newInstance();
System.out.println(clazzes.getId());
System.out.println(clazzes.getName());
System.out.println(Arrays.toString(clazzes.getHobbies()));
//---------------------------------Array---------------------------------
//---------------------------------0---------------------------------
int[] ints0 = (int[])Array.newInstance(int.class, 3);
Array.setInt(ints0, 0, 0);
Array.setInt(ints0, 1, 1);
Array.setInt(ints0, 2, 2);
// //Array.setInt(ints, 3, 3); //java.lang.ArrayIndexOutOfBoundsException
System.out.println(Arrays.toString(ints0));
//---------------------------------1---------------------------------
int[][][] ints3 = (int[][][])Array.newInstance(int.class,2,3,4);
System.out.println(ints3.length);
System.out.println(ints3[0].length);
System.out.println(ints3[0][0].length);
int[][] ints3_1_row0_content = new int[][]{{1,2,3,4},{1,2,3,4},{1,2,3,4}};
int[][] ints3_1_row1_content = new int[][]{{11,22,33,44},{11,22,33,44},{11,22,33,44}};
Array.set(ints3, 0, ints3_1_row0_content);
Array.set(ints3, 1, ints3_1_row1_content);
System.out.println(Arrays.deepToString(ints3));
//---------------------------------2---------------------------------
int[][] ints2 = (int[][])Array.newInstance(int.class, 4,4);
for (int i=0; i<4; i++) {
ints2[i] = (int[]) Array.newInstance(int.class, i + 1);//重新创建每个第一位数组的长度
}
for(int[] array : ints2){
for(int content : array){
System.out.print(content + ",");
}
System.out.println();
}
//---------------------------------4---------------------------------
int[][][] ints4 = new int[1][2][3];
Class<?> clazzz = ints4.getClass();
int dim = 0;
while(clazzz.isArray()){
dim ++;
clazzz = clazzz.getComponentType();
}
System.out.println(dim);
System.out.println(ints4.getClass().isArray());
System.out.println(ints4.getClass().getComponentType().getName());
System.out.println(ints4.getClass().getComponentType().getComponentType().getName());
System.out.println(ints4.getClass().getComponentType().getComponentType().getComponentType().getName());
// System.out.println(ints2.getClass().getComponentType().getComponentType().getComponentType().getComponentType().getName());//java.lang.NullPointerException
}
}
5.注解 Annotation
Java代码
package com.java.new_features_jdk5;
/**
* 比较常用的注释:
* SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。
Deprecated 用"@Deprecated" 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
Override 表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
* @author yuahan
*
*/
public class _Annotation {
public static void main(String[] args) {
}
}
6.泛型
Java代码
package com.java.new_features_jdk5;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Java语言的泛型类似于C++中的模板. 但是这仅仅是基于表面的现象。Java语言的泛型基本上完全在编译器中实现的,由编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。 这种实现称为"擦除"(编译器使用泛型类型信息保证类型安全,然后在生成字节码之前将其清除)
需要注意的地方:
* 1. 泛型不是协变的
协变:Java 语言中的数组是协变的(covariant),也就是说, 如果 Integer 扩展了 Number,那么不仅 Integer 是 Number,而且 Integer[] 也是 Number[],在要求Number[] 的地方完全可以传递或者赋予 Integer[]。
但是,泛型并不是协变的。 如果Number是Integer的超类型,但是,如果需要List<Integer>的时候, 并不容许传递List<Number>,它们并不等价。
不允许的理由很简单,这样会破坏要提供的类型安全泛型。
如:
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
List<Number> list2=list;//编译错误.
list2.add(new Float(19.0f));
}
2. 延迟构造
因为可以擦除功能,所以List<Integer>和List<String>是同一个类,编译器在编译List<V>的时候,只生成一个类。所以,运行时,不能区分List<Integer>和List<String>(实际上,运行时都是List,类型被擦除了),
用泛型类型参数标识类型的变量的构造就成了问题。运行时缺乏类型信息,这给泛型容器类和希望创建保护性副本的泛型类提出了难题。
3. 不能用通配符来帮助构造一个类(容器,数组等),因为根本不知道类型,不能确定该构造函数是否存在
class Foo{
public void doSomething(Set<?> set){
Set<?> copy = new HashSet<?>(set);//编译出错,不能用通配符类型的参数调用泛型构造函数
}
}
或者
class ArrayList<V>{
V[] content;
public ArrayList() {
content = new V[10];//编译出错,不能实例化用类型参数表示的类型数组
}
}
不过可以用Object类帮助实现,不过看上去很不舒服。
class Foo{
public void doSomething(Set<?> set){
Set<?> copy = new HashSet<Object>(set);
}
}
或者
class ArrayList<V>{
V[] content;
public ArrayList() {
content = (V[])new Object[10];
}
}
4. 擦除
因为泛型基本上都是在JAVA编译器中而不是运行库中实现的,所以在生成字节码的时候,差不多所有关于泛型类型的类型信息都被“擦除”了, 换句话说,编译器生成的代码与手工编写的不用泛型、检查程序类型安全后进行强制类型转换所得到的代码基本相同。
擦除意味着,一个类不能同时实现 Comparable<String>和Comparable<Number>,因为事实上,两者都在同一个接口中,指定同一个compareTo()方法。
5. 泛型的规则和限制
(1 泛型的参数类型只能是类( class )类型,而不能是简单类型。
比如, <int> 是不可使用的。
(2 可以声明多个泛型参数类型,比如 <T, P,Q…> ,同时还可以嵌套泛型,例如: <List<String>>.
(3 泛型 的参数 类 型可以使用 extends 语 句,例如 <T extends superclass> 。
(4 泛型的参数类型可以使用 super 语句,例如 < T super childclass> 。
(5 泛型还可以使用通配符,例如 <? e xtends ArrayList>
* @author yuahan
*
*/
public class _Generic <T> {
public void array2Collection(T[] array, Collection<T> collection){
if(array != null && collection != null){
for(T content : array ){
collection.add(content);
}
}
}
public static void main(String[] args) {
_Generic<Integer> generic = new _Generic<Integer>();
Integer[] array = new Integer[]{1,2,3,4};
List<Integer> list = new ArrayList<Integer>();
generic.array2Collection(array, list);
System.out.println(list);
}
}
7.可变参数(Vararg)
Java代码
package com.java.new_features_jdk5;
/**
*
* 可变参数可以解决代码冗余的问题。
* 如:
* public int max(int i, int j);
* public int max(int i, int j, int k);
* 可以简化成
* public int max(int... num);
*
* 可以将可变参数视为长度可变的数组。不过需要注意以下问题 :
* 1. 变长参数一定要放在最后面
max(int ... nums, int temp)// error
* 2. 可变参数不能与数组参数并存
max(int[] nums)//error
* @author yuahan
*
*/
public class _Var_Arg {
public static int max(int ... nums){
int max = Integer.MIN_VALUE;
for(int num : nums){
if(num >= max){
max = num;
}
}
return max;
}
public static void main(String[] args) {
int max1 = _Var_Arg.max(1,2,3,4,5);
int max2 = _Var_Arg.max(new int[]{1,2,3,4,5});
System.out.println(max1);
System.out.println(max2);
}
}
8.格式化输入输出
不太喜欢c的输出格式,没有进行尝试。
Java代码
package com.java.new_features_jdk5;
/**
*
* 一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com.....ClassName.*;
* 这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。
* 然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用。
* 这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(...);就可以将其写入一个静态方法print(...),在使用时直接print(...)就可以了。
* 但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便。
* @author yuahan
*
*/
public class _Static_Import {
public static void main(String[] args) {
}
}
2.新增加的for循环
Java代码
package com.java.new_features_jdk5;
import java.util.ArrayList;
import java.util.List;
/**
* 增强的for循环,可以使用在数组和容器中
* @author yuahan
*
*/
public class _For {
@SuppressWarnings("serial")
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,9,10};
for(int num : array){
System.out.print(num + " ");
}
System.out.println();
List<Integer> list = new ArrayList<Integer>(){{
this.add(1);
this.add(2);
this.add(3);
this.add(4);
this.add(5);
this.add(6);
this.add(7);
this.add(8);
this.add(9);
this.add(10);
}};
for(int num : list){
System.out.print(num + " ");
}
}
}
3.枚举 Enum
Java代码
package com.java.new_features_jdk5;
/**
*
* 你可以将枚举类型视为特殊的类,因此几乎可以像创建普通类那样创建枚举。
* 枚举类型有附加的特性,有EnumMap和EnumSet两个类。实例化方法中都需要传入枚举类型的类类型,如:
* EnumSet<_Enum> set = EnumSet.noneOf(_Enum.class);
EnumMap<_Enum,String> map = new EnumMap<_Enum,String>(_Enum.class);
枚举可以有自己的构造方法,不过构造方法只能私有,这样外部是不能构造出新的枚举中的实例,而只是调用其中的实例。
* @author yuahan
*
*/
public enum _Enum {
Better(90),
Good(80),
Ok(70),
Bad(60),
Worse;
private int value;
private _Enum() {
this.value = 30;
}
private _Enum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public static _Enum[] getEnumValues(){
return _Enum.values();
}
public static void _ValuesOf(){
// _Enum test = _Enum.valueOf("test");//error
// System.out.println(test);
_Enum Better = _Enum.valueOf("Better");
System.out.println(Better);
}
public static void main(String[] args) {
for(_Enum mark : _Enum.getEnumValues()){
switch(mark){
case Better:
System.out.println(_Enum.Better);
break;
case Good:
System.out.println(_Enum.Good);
break;
case Ok:
System.out.println(_Enum.Ok);
break;
case Bad:
System.out.println(_Enum.Bad);
break;
case Worse:
System.out.println(_Enum.Worse);
break;
}
}
_Enum._ValuesOf();
System.out.println(_Enum.Better.getValue());
}
}
4.反射 Reflect
Java代码
package com.java.new_features_jdk5;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
/**
* Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。
* Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性
* JavaDoc 中对每个类和其中的方法有非常详细介绍。主要有:
* Class ------- java.lang
* Package ------- java.lang
*
* Array
* Field
* Method
* Modifier
* Constructor
* @author yuahan
*
*/
public class _Reflect {
private int id;
private String name;
private String[] hobbies;
public _Reflect(){}
public _Reflect(int id){
this.id = id;
}
public _Reflect(int id, String name, String[] hobbies) {
super();
this.id = id;
this.name = name;
this.hobbies = hobbies;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public static void main(String[] args) throws Exception{
//---------------------------------basic---------------------------------
System.out.println(_Reflect.class.getSimpleName());
System.out.println(_Reflect.class.getName());
System.out.println(_Reflect.class.getPackage());
System.out.println(_Reflect.class.getSuperclass().getName());
System.out.println(int[].class.getName());
System.out.println(_Reflect[].class.getName());
// //--------------------------------- Method ---------------------------------
Method[] methods = _Reflect.class.getMethods();
for(Method method : methods){
System.out.println(method + ": " +method.getDeclaringClass().getName());
}
// //--------------------------------- isXXX ---------------------------------
System.out.println(Comparable.class.isInterface());
System.out.println(int.class.isPrimitive());
System.out.println(int[].class.isArray());
// //--------------------------------- Modifier 修饰符 ---------------------------------
System.out.println(Modifier.isPublic(_Reflect.class.getModifiers()));
Class<?>[] classes = null;
System.out.println(Modifier.isPublic(_Reflect.class.getMethod("getId",classes).getModifiers()));
//isAssignableFrom isInstance
System.out.println(Number.class.isAssignableFrom(Integer.class));
System.out.println(Number.class.isInstance(1));
//---------------------------------Field---------------------------------
_Reflect _Reflect = new _Reflect();
System.out.println(_Reflect.getId());
System.out.println(_Reflect.getName());
System.out.println(Arrays.toString(_Reflect.getHobbies()));
Field[] fields = _Reflect.class.getDeclaredFields();
for(Field field : fields){
if(field.getType() == int.class){
field.setAccessible(true);
field.setInt(_Reflect, 1);
}else if(field.getType() == String.class){
field.setAccessible(true);
field.set(_Reflect, "1");
}else if(field.getType() == String[].class){
field.setAccessible(true);
field.set(_Reflect, new String[]{"1","1"});
}
}
System.out.println(_Reflect.getId());
System.out.println(_Reflect.getName());
System.out.println(Arrays.toString(_Reflect.getHobbies()));
// //---------------------------------new instance---------------------------------
Constructor<_Reflect> constructor = _Reflect.class.getConstructor(new Class[]{int.class,String.class,String[].class});
_Reflect _reflect = constructor.newInstance(new Object[]{1,"1",new String[]{"1","1"}});
System.out.println(_reflect.getId());
System.out.println(_reflect.getName());
System.out.println(Arrays.toString(_Reflect.getHobbies()));
Class<?> clazz = Class.forName("com.java.new_features_jdk5._Reflect");
_Reflect clazzes = (_Reflect)clazz.newInstance();
System.out.println(clazzes.getId());
System.out.println(clazzes.getName());
System.out.println(Arrays.toString(clazzes.getHobbies()));
//---------------------------------Array---------------------------------
//---------------------------------0---------------------------------
int[] ints0 = (int[])Array.newInstance(int.class, 3);
Array.setInt(ints0, 0, 0);
Array.setInt(ints0, 1, 1);
Array.setInt(ints0, 2, 2);
// //Array.setInt(ints, 3, 3); //java.lang.ArrayIndexOutOfBoundsException
System.out.println(Arrays.toString(ints0));
//---------------------------------1---------------------------------
int[][][] ints3 = (int[][][])Array.newInstance(int.class,2,3,4);
System.out.println(ints3.length);
System.out.println(ints3[0].length);
System.out.println(ints3[0][0].length);
int[][] ints3_1_row0_content = new int[][]{{1,2,3,4},{1,2,3,4},{1,2,3,4}};
int[][] ints3_1_row1_content = new int[][]{{11,22,33,44},{11,22,33,44},{11,22,33,44}};
Array.set(ints3, 0, ints3_1_row0_content);
Array.set(ints3, 1, ints3_1_row1_content);
System.out.println(Arrays.deepToString(ints3));
//---------------------------------2---------------------------------
int[][] ints2 = (int[][])Array.newInstance(int.class, 4,4);
for (int i=0; i<4; i++) {
ints2[i] = (int[]) Array.newInstance(int.class, i + 1);//重新创建每个第一位数组的长度
}
for(int[] array : ints2){
for(int content : array){
System.out.print(content + ",");
}
System.out.println();
}
//---------------------------------4---------------------------------
int[][][] ints4 = new int[1][2][3];
Class<?> clazzz = ints4.getClass();
int dim = 0;
while(clazzz.isArray()){
dim ++;
clazzz = clazzz.getComponentType();
}
System.out.println(dim);
System.out.println(ints4.getClass().isArray());
System.out.println(ints4.getClass().getComponentType().getName());
System.out.println(ints4.getClass().getComponentType().getComponentType().getName());
System.out.println(ints4.getClass().getComponentType().getComponentType().getComponentType().getName());
// System.out.println(ints2.getClass().getComponentType().getComponentType().getComponentType().getComponentType().getName());//java.lang.NullPointerException
}
}
5.注解 Annotation
Java代码
package com.java.new_features_jdk5;
/**
* 比较常用的注释:
* SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。
Deprecated 用"@Deprecated" 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
Override 表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
* @author yuahan
*
*/
public class _Annotation {
public static void main(String[] args) {
}
}
6.泛型
Java代码
package com.java.new_features_jdk5;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Java语言的泛型类似于C++中的模板. 但是这仅仅是基于表面的现象。Java语言的泛型基本上完全在编译器中实现的,由编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。 这种实现称为"擦除"(编译器使用泛型类型信息保证类型安全,然后在生成字节码之前将其清除)
需要注意的地方:
* 1. 泛型不是协变的
协变:Java 语言中的数组是协变的(covariant),也就是说, 如果 Integer 扩展了 Number,那么不仅 Integer 是 Number,而且 Integer[] 也是 Number[],在要求Number[] 的地方完全可以传递或者赋予 Integer[]。
但是,泛型并不是协变的。 如果Number是Integer的超类型,但是,如果需要List<Integer>的时候, 并不容许传递List<Number>,它们并不等价。
不允许的理由很简单,这样会破坏要提供的类型安全泛型。
如:
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
List<Number> list2=list;//编译错误.
list2.add(new Float(19.0f));
}
2. 延迟构造
因为可以擦除功能,所以List<Integer>和List<String>是同一个类,编译器在编译List<V>的时候,只生成一个类。所以,运行时,不能区分List<Integer>和List<String>(实际上,运行时都是List,类型被擦除了),
用泛型类型参数标识类型的变量的构造就成了问题。运行时缺乏类型信息,这给泛型容器类和希望创建保护性副本的泛型类提出了难题。
3. 不能用通配符来帮助构造一个类(容器,数组等),因为根本不知道类型,不能确定该构造函数是否存在
class Foo{
public void doSomething(Set<?> set){
Set<?> copy = new HashSet<?>(set);//编译出错,不能用通配符类型的参数调用泛型构造函数
}
}
或者
class ArrayList<V>{
V[] content;
public ArrayList() {
content = new V[10];//编译出错,不能实例化用类型参数表示的类型数组
}
}
不过可以用Object类帮助实现,不过看上去很不舒服。
class Foo{
public void doSomething(Set<?> set){
Set<?> copy = new HashSet<Object>(set);
}
}
或者
class ArrayList<V>{
V[] content;
public ArrayList() {
content = (V[])new Object[10];
}
}
4. 擦除
因为泛型基本上都是在JAVA编译器中而不是运行库中实现的,所以在生成字节码的时候,差不多所有关于泛型类型的类型信息都被“擦除”了, 换句话说,编译器生成的代码与手工编写的不用泛型、检查程序类型安全后进行强制类型转换所得到的代码基本相同。
擦除意味着,一个类不能同时实现 Comparable<String>和Comparable<Number>,因为事实上,两者都在同一个接口中,指定同一个compareTo()方法。
5. 泛型的规则和限制
(1 泛型的参数类型只能是类( class )类型,而不能是简单类型。
比如, <int> 是不可使用的。
(2 可以声明多个泛型参数类型,比如 <T, P,Q…> ,同时还可以嵌套泛型,例如: <List<String>>.
(3 泛型 的参数 类 型可以使用 extends 语 句,例如 <T extends superclass> 。
(4 泛型的参数类型可以使用 super 语句,例如 < T super childclass> 。
(5 泛型还可以使用通配符,例如 <? e xtends ArrayList>
* @author yuahan
*
*/
public class _Generic <T> {
public void array2Collection(T[] array, Collection<T> collection){
if(array != null && collection != null){
for(T content : array ){
collection.add(content);
}
}
}
public static void main(String[] args) {
_Generic<Integer> generic = new _Generic<Integer>();
Integer[] array = new Integer[]{1,2,3,4};
List<Integer> list = new ArrayList<Integer>();
generic.array2Collection(array, list);
System.out.println(list);
}
}
7.可变参数(Vararg)
Java代码
package com.java.new_features_jdk5;
/**
*
* 可变参数可以解决代码冗余的问题。
* 如:
* public int max(int i, int j);
* public int max(int i, int j, int k);
* 可以简化成
* public int max(int... num);
*
* 可以将可变参数视为长度可变的数组。不过需要注意以下问题 :
* 1. 变长参数一定要放在最后面
max(int ... nums, int temp)// error
* 2. 可变参数不能与数组参数并存
max(int[] nums)//error
* @author yuahan
*
*/
public class _Var_Arg {
public static int max(int ... nums){
int max = Integer.MIN_VALUE;
for(int num : nums){
if(num >= max){
max = num;
}
}
return max;
}
public static void main(String[] args) {
int max1 = _Var_Arg.max(1,2,3,4,5);
int max2 = _Var_Arg.max(new int[]{1,2,3,4,5});
System.out.println(max1);
System.out.println(max2);
}
}
8.格式化输入输出
不太喜欢c的输出格式,没有进行尝试。
相关文章推荐
- struts技术有什么优点、好处?
- JAVA多线程--信号量(Semaphore)
- 深入理解Java的接口和抽象类
- Java记录 -42- Java Collection
- Java 7 的7个新特性
- struts2常用标签详解-在项目中使用struts2标签
- eclipse/myeclipse安装svn插件
- Java 基础之认识 Annotation
- 10007---SpringMVC 使用 POJO 对象绑定请求参数值,解决中文乱码
- 构建Gradle范例项目之构建Java项目
- JAVA将Excel中的报表导出为图片格式(一)问题背景
- 序列化与反序列化
- java设计模式之单例模式(几种写法及比较)
- Nachos导入eclipse
- JAVA---多线程之Callable与Future,FutureTask,及其简单应用
- 如何创建不可变(Immutable)的Java类或对象
- java泛型详解
- Java开源的支持xpath的html解析器介绍--JsoupXpath
- 通过Java插入MYSQL的DATETIME类型
- Java中的关键字和标识符