建议 90:
@Retention:注解的保留位置
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target:注解的作用目标
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
建议 91:
注解与枚举结合:经典场景(访问控制设计)
建议:92:
@override
在java 1.5版本上,不能覆盖接口的方法,1.6之后可以
建议:93:
java 泛型的类型是类型擦除的
范型数组初始化时不能声明泛型类型
instanceof 不允许存在泛型参数
建议:94:
如何初始化泛型数组
public class Foo<
T> {
private T t;
private T[] tArray;
private List< T> list = new ArrayList< T>();
public Foo(Class< T> tType){
try {
t = ( T) tType.newInstance();
tArray = ( T[]) Array. newInstance(tType, 5);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private T t;
private T[] tArray;
private List< T> list = new ArrayList< T>();
public Foo(Class< T> tType){
try {
t = ( T) tType.newInstance();
tArray = ( T[]) Array. newInstance(tType, 5);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
调用的时候,把T的类型传入就可以了
Foo<BaseCityInfo> f =
new Foo<BaseCityInfo>(BaseCityInfo.
class);
建议 95:强制生命泛型的实际类型
像在工具类的static方法中,不能将泛型加到类上了,这是可以加到方法的前面。
public class ArrayUtils {
public static < T> List< T> asList( T...t){
List< T> list = new ArrayList< T>();
Collections. addAll(list, t);
return list;
}
public static < T> List< T> asList( T...t){
List< T> list = new ArrayList< T>();
Collections. addAll(list, t);
return list;
}
}
当我们在使用的时候,
List<String> list1 =
new ArrayUtils().
asList(
"A",
"B");
List list2 = ArrayUtils. asList();
List<Number> list3 = ArrayUtils.<Number> asList( 1, 2, 3.2);
list2.add( 11);
list2.add( "dd");
List list2 = ArrayUtils. asList();
List<Number> list3 = ArrayUtils.<Number> asList( 1, 2, 3.2);
list2.add( 11);
list2.add( "dd");
String a = list1.get(0);
String b = (String) list2.get(0); //由于这里没有做强制类型转换,所以在取时转换
Number c = list3.get(
0);
println(list1);
println(list2);
println(list3);
println(list1);
println(list2);
println(list3);
println l=class java.lang.String
println l=A
println l=class java.lang.String
println l=B
println l=class java.lang.Integer
println l=11
println l=class java.lang.String
println l=dd
println l=class java.lang.Integer
println l=1
println l=class java.lang.Integer
println l=2
println l=class java.lang.Double
println l=3.2
private void println(List<?
extends Object> list){
for(Object l :list){
for(Object l :list){
System.out.println("println l="+l.getClass());
System.out.println(
"println l="+l);
}
}
当然输出还可以按照下面这样写,但是这样写的话,在list2取的时候,强制转化就不能都转string了。
private <
E>
void println2(List<?
extends
E> list){
for( E l :list){
Log. v( "XPC", "println l="+l.getClass());
Log. v( "XPC", "println l="+l);
}
for( E l :list){
Log. v( "XPC", "println l="+l.getClass());
Log. v( "XPC", "println l="+l);
}
}
建议 96:
泛型extends VS super
在一般的讲解中,extends说的是子类,上界,
super说的是父类,下界。(我想不可能这么多人一起写错,所以应该是我理解有问题,希望有人可以指出)
我的理解是这样的,无论extends还是super,泛型出来的类型都是子类,
只是extends 涉及到get,也就是读取相关,就是说只能读取,不能写入
而super涉及的事put,就是写入,当然他就不能读取了。
比较典型的是Collections.copy方法
public static <
T>
void copy(List<?
super
T> dest,List<?
extends
T> src){
for( int i= 0;i< srcSize;i++){
dest.set(i,src.get(i));
}
for( int i= 0;i< srcSize;i++){
dest.set(i,src.get(i));
}
}
自我理解测试例子:
song s =
new song();
person p = new person();
Parent pa = new Parent();
person p = new person();
Parent pa = new Parent();
List<? super Parent> list = new ArrayList<>();
list.add(s); //add 只有super可以,如果是extends是编译不过的。
list.add(p);
list.add(pa);
list.add(pa);
song s1 = (song) list.get(0);
Parent s3 = (Parent) list.get(2);//super get出来的类型都是Object的,所以无论什么都要转型,
当然如果是
List<?
extends Parent> list =
new ArrayList<>();
// list.add(s); add 肯定是编译不过的
// list.add(p);
// list.add(pa);
// list.add(s); add 肯定是编译不过的
// list.add(p);
// list.add(pa);
song s1 = (song)list.get(0);//这个返回的类型是Parent,
Parent s3 = list.get(
2);
建议 98 :建议采用顺序是 List<T>,List<?>,List<Object>
建议 99:严格限定泛型类型采用多重限界
public static <T extends Staff & Passenger> void discount(){...}