effective java —— 方法

以下主要针对方法参数,返回值,方法签名等细节的优化,以提高程序的健壮性和灵活性。值得大家阅读

private  SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

/**
* 构造器或公用方法 第一先检查参数有效性,防止错误深入蔓延,不便问题查找
*/
public  void f1(Object o) {
   if (o == null) {
       throw new IllegalArgumentException("o not to be null");
   }
   //... other codes
}

/**
* 私有方法 使用断言 调试时出错快速中断程序 必须开启断言  配置 VM  -ea 开启
*/
private  void f2(Object o) {
   assert (o != null) : "o is not null";
   // ... other codes
}

/**
* 必要时进行保护性拷贝
*/
private  void f3() throws Exception {
   Date startDate = simpleDateFormat.parse("2020-01-01");
   Date endDate = simpleDateFormat.parse("2020-01-05");
   Period period = new Period(startDate, endDate);
   System.out.println(period); //Period{startDate=2020-01-01, endDate=2020-01-05}
   endDate.setYear(0); // 在引用参数的外部改动时,破坏了对象内部限制
   System.out.println(period); //Period{startDate=2020-01-01, endDate=1900-01-05}
   period.getEndDate().setYear(1); // 对对象的操作,破坏了对象内部的限制
   System.out.println(period); //Period{startDate=2020-01-01, endDate=1901-01-05}
}

/**
* 避免过长参数列表 参数数量最好不要超过4个 减少参数个数 有3种方法
* 1.把一个方法分成多个方法
* 2.增加辅助类 把参数放到辅助类内 通过辅助类来传递参数
* 3.使用构建器 先把参数传入构建器 然后通过构建器生成对象
* 4.对于参数类型优先使用接口而非类
* 5.对于boolean参数 优先使用枚举类型
*/

public  void f4() {
   Student.Builder studentBuilder = new Student.Builder()
           .setName("张三")
           .setAge(25)
           .setHeight(1.8);
   Student student = studentBuilder.builder();
   System.out.println(student); // Student{name='张三', age=25, height=1.8}
}

/**
* 慎用重载
* 1.重载 在编译器时选择相对应方法执行 选择是静态的
* 2.重写(Override) 在运行期选择相对应的方法执行  选择是动态的
* 3.可以使用更改签名来替代重载 例如 ObjectOutputStream 里的 writeInt(Int n), writeBoolean(boolean b) ...
*/

private  void f5() {
   Collection<?>[] collections = {
           new HashSet<String>(),
           new ArrayList<String>(),
           new HashMap<String, String>().values()};

   for (Collection<?> collection : collections) {
       printCollections(collection);
       // 结果是 collection collection collection
       // 编译器 类型都是 Collection<?> 所以选择的 printCollections(Collection<?> collection)
   }

   Animal[] animals = {new Animal(), new Dog(), new Cat()};
   for (Animal animal : animals) {
       animal.printName();
       // 结果是 Animal, Dog, Cat
   }

   Set<Integer> set = new HashSet<>();
   List<Integer> list = new ArrayList<>();
   for (int i = -3; i < 3; i++) {
       set.add(i);
       list.add(i);
   }

   for (int i = 0; i < 3; i++) {
       set.remove(i); //
       list.remove(i); // List 里有两个重载方法 remove(int) remove(Object) 这里实际调用的是前者
       // list.remove(Integer.valueOf(i));  // 需要强制转化下
   }

   System.out.println(set + " " + list); // [-1, -2, -3] [-2, 0, 2]
}

private  void printCollections(Set<?> set) {
   System.out.println("set");
}

private  void printCollections(List<?> list) {
   System.out.println("list");
}

private  void printCollections(Collection<?> collection) {
   System.out.println("collection");
}

/**
* 慎用可变参数
* 1.可变参数 允许一个参数都不传
* 2.当至少需要一个参数时 我们可以指定一个参数  而不是对可变参数进行数量判断
*/

public  void f6() {
   int sum = sum();
   System.out.println(sum); // 0

   int min = min(2, 4, 4, 6, 7, 8);
   System.out.println(min); // 2

   List<String> list = Arrays.asList("sfa", "sf", "sadf");
   System.out.println(list); // [sfa, sf, sadf]

   int[] nArr = {1,2,3,4,5};
   System.out.println(Arrays.asList(nArr)); // [[I@a09ee92]
   System.out.println(Arrays.asList(1, 0, 2 ,3 ,4 )); // [1, 0, 2, 3, 4]
   System.out.println(Arrays.toString(nArr)); // [1, 2, 3, 4, 5]
}

private  int sum(int... args) {
   int sum = 0;
   for (int n : args) {
       sum += n;
   }

   return sum;
}

private  int min(int first, int... args) {
   // if (args.length == 0) {throw new Exception("至少传入一个参数")}
   int min = first;
   for (int n : args) {
       min = Math.min(min, n);
   }

   return min;
}

/**
* 返回0长度的数组或集合而非null
* 1.返回null 调用的地方就需要对 null进行判断 稍不注意就会出现空指针异常
* 2.如果觉得返回空数组或空集合 浪费内存空间  可以预选定义一个空集合或数组
*/
private  final String[] EMPTY_ARR = {};
private  final List<String> EMPTY_LIST = new ArrayList<>();
public  String[] getArr() {
   return EMPTY_ARR;
}

public  List<String> getList() {
   return EMPTY_LIST;
}

/**
* 为所有的Export的API编写文档注释
*/

/**
* 获取指定id的学生姓名
* @param id 学生id
* @return 学生姓名
* @see String
*/
public String getName(int id) {
   return "张三";
}

public  class Period {
   private Date startDate;
   private Date endDate;

   public Period(Date startDate, Date endDate) {
       if (startDate.compareTo(endDate) > 0) {
           throw new IllegalArgumentException("开始时间不能大于结束时间");
       }
       this.startDate = startDate;
       this.endDate = endDate;

       // 必要时进行保护性拷贝
       // this.startDate = new Date(startDate.getTime());
       // this.endDate = new Date(endDate.getTime());
   }

   @Override
   public String toString() {
       return "Period{" +
               "startDate=" + simpleDateFormat.format(startDate) +
               ", endDate=" + simpleDateFormat.format(endDate) +
               '}';
   }

   public Date getStartDate() {
       return this.startDate;
       // 防止对象外部的修改,破坏对象内部的限制
       //return new Date(this.startDate.getTime());
   }

   public Date getEndDate() {
       return endDate;
       // 防止对象外部的修改,破坏对象内部的限制
       //return new Date(this.endDate.getTime());
   }
}

public  class Student {
   private String name;
   private int age;
   private double height;

   Student(Builder builder) {
       this.name = builder.name;
       this.age = builder.age;
       this.height = builder.height;
   }

   @Override
   public String toString() {
       return "Student{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", height=" + height +
               '}';
   }

   public  class Builder {
       private String name;
       private int age;
       private double height;

       public Builder() {
       }

       ;

       public Builder setName(String name) {
           this.name = name;
           return this;
       }

       public Builder setAge(int age) {
           this.age = age;
           return this;
       }

       public Builder setHeight(double height) {
           this.height = height;
           return this;
       }

       public Student builder() {
           if (StringUtils.isEmpty(name)) {
               throw new IllegalArgumentException("请设置name");
           }
           if (age == 0) {
               throw new IllegalArgumentException("请设置age");
           }
           if (height == 0) {
               throw new IllegalArgumentException("请设置height");
           }
           return new Student(this);
       }
   }
}

public  class Animal {
   public void printName() {
       System.out.println("Animal");
   }
}

public  class Dog extends Animal {
   @Override
   public void printName() {
       System.out.println("Dog");
   }
}

public  class Cat extends Animal {
   @Override
   public void printName() {
       System.out.println("Cat");
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值