编写高质量代码之读书笔记2

建议 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;
    private  T[]  tArray;
    private List< Tlist new ArrayList< T>();


    public Foo(Class< T> tType){
        try {
            = ( 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;
    }
}
当我们在使用的时候,
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");
String a = list1.get(0);
String b = (String) list2.get(0);  //由于这里没有做强制类型转换,所以在取时转换
Number c = list3.get( 0);

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){
      System.out.println("println   l="+l.getClass());
      System.out.println( "println   l="+l);
   }
}
当然输出还可以按照下面这样写,但是这样写的话,在list2取的时候,强制转化就不能都转string了。
private < Evoid println2(List<?  extends  E> list){
    for( 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 < Tvoid copy(List<?  super  T> dest,List<?  extends  T> src){
    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();

List<? super Parent> list = new ArrayList<>();
list.add(s);   //add 只有super可以,如果是extends是编译不过的。
list.add(p);
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);

        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(){...}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值