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

本文详细介绍了Java中的注解使用方法,包括@Retention、@Target等元注解的作用及应用场景,并深入探讨了泛型的基本概念、初始化方式以及泛型在实际编程中的运用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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



内容概要:本文介绍了多种开发者工具及其对开发效率的提升作用。首先,介绍了两款集成开发环境(IDE):IntelliJ IDEA 以其智能代码补全、强大的调试工具和项目管理功能适用于Java开发者;VS Code 则凭借轻量级和多种编程语言的插件支持成为前端开发者的常用工具。其次,提到了基于 GPT-4 的智能代码生成工具 Cursor,它通过对话式编程显著提高了开发效率。接着,阐述了版本控制系统 Git 的重要性,包括记录代码修改、分支管理和协作功能。然后,介绍了 Postman 作为 API 全生命周期管理工具,可创建、测试和文档化 API,缩短前后端联调时间。再者,提到 SonarQube 这款代码质量管理工具,能自动扫描代码并检测潜在的质量问题。还介绍了 Docker 容器化工具,通过定义应用的运行环境和依赖,确保环境一致性。最后,提及了线上诊断工具 Arthas 和性能调优工具 JProfiler,分别用于生产环境排障和性能优化。 适合人群:所有希望提高开发效率的程序员,尤其是有一定开发经验的软件工程师和技术团队。 使用场景及目标:①选择合适的 IDE 提升编码速度和代码质量;②利用 AI 编程助手加快开发进程;③通过 Git 实现高效的版本控制和团队协作;④使用 Postman 管理 API 的全生命周期;⑤借助 SonarQube 提高代码质量;⑥采用 Docker 实现环境一致性;⑦运用 Arthas 和 JProfiler 进行线上诊断和性能调优。 阅读建议:根据个人或团队的需求选择适合的工具,深入理解每种工具的功能特点,并在实际开发中不断实践和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值