使类和成员的可访问性最小化
包含公有可变域的类通常不是线程安全的
在仔细设计了一个最小的公有api之后,应该防止把散乱的类、接口或者成员变成api的一部分
除了公有静态final域的特殊情形之外(此时它们充当常量),公有类都不应该包含公有域,并且要确保公有静态final域所引用的对象都是不可变的
要在公有类中使用访问方法而非公有域
package codeTemplate.effectiveJava.bean;
import lombok.Getter;
import lombok.Setter;
import java.util.Arrays;
import java.util.List;
@Setter
@Getter
public class CommonBean {
private String name = "123";
//Make this final field static too.
private final String finalName = "123";
private static String staticName = "123";
//常量【finalStaticName】命名应全部大写并以下划线分隔
private static final String FINAL_STATIC_NAME = "123";
private List<String> names = Arrays.asList("123", "234");
private final List<String> finalNames = Arrays.asList("123", "234");
private static List<String> staticNames = Arrays.asList("123", "234");
//常量【finalStaticNames】命名应全部大写并以下划线分隔
private static final List<String> FINAL_STATIC_NAMES = Arrays.asList("123", "234");
private PhoneArea phoneArea;
private PhoneArea phoneAreaNew = new PhoneArea("China");
//Variable 'finalPhoneArea' might not have been initialized
private final PhoneArea finalPhoneArea;
//Make this final field static too.
private final PhoneArea finalPhoneAreaNew = null;
private static PhoneArea staticPhoneArea;
//Variable 'staticFinalPhoneAreaNew' might not have been initialized
private static final PhoneArea staticFinalPhoneArea;
//常量【staticFinalPhoneAreaNew】命名应全部大写并以下划线分隔
private static final PhoneArea STATIC_FINAL_PHONE_AREA_NEW = null;
//Make publicName a static final constant or non-public and provide accessors if needed.
public String publicName = "123";
//Make this final field static too.
public final String publicFinalName = "123";
//Make publicStaticName a static final constant or non-public and provide accessors if needed.
public static String publicStaticName = "123";
//常量【publicFinalStaticName】命名应全部大写并以下划线分隔
public static final String publicFinalStaticName = "123";
//Make publicNames a static final constant or non-public and provide accessors if needed.
public List<String> publicNames = Arrays.asList("123", "234");
public final List<String> publicFinalNames = Arrays.asList("123", "234");
//Make publicNames a static final constant or non-public and provide accessors if needed.
public static List<String> publicStaticNames = Arrays.asList("123", "234");
//常量【publicFinalStaticNames】命名应全部大写并以下划线分隔
public static final List<String> publicFinalStaticNames = Arrays.asList("123", "234");
//Make publicPhoneArea a static final constant or non-public and provide accessors if needed
public PhoneArea publicPhoneArea;
//Make publicPhoneArea a static final constant or non-public and provide accessors if needed
public PhoneArea publicPhoneAreaNew = new PhoneArea("China");
//Variable 'publicFinalPhoneArea' might not have been initialized
public final PhoneArea publicFinalPhoneArea;
//Make this final field static too.
public final PhoneArea publicFinalPhoneAreaNew=null;
//Make publicStaticPhoneAreaNew a static final constant or non-public and provide accessors if needed.
public static PhoneArea publicStaticPhoneArea;
//Variable 'publicStaticFinalPhoneArea' might not have been initialized
public static final PhoneArea publicStaticFinalPhoneArea;
//常量【publicStaticFinalPhoneAreaNew】命名应全部大写并以下划线分隔
public static final PhoneArea publicStaticFinalPhoneAreaNew=null;
}
总结
私有属性
- 常量时final需要和static共同使用,引用对象时可以单独使用,都一定要初始化。
- static final 属性命名应全部大写并以下划线分隔,为常量
公有属性
- 常量都需要是static final
- 引用类型static final修饰为常量,可以只有final,不静态
- static final 属性命名应全部大写并以下划线分隔
- final修饰的都要初始化
最好的使用
private String name = "123";
private static String staticName = "123";
private static final String FINAL_STATIC_NAME = "123";
private final List<String> finalNames=new ArrayList<>();
public static final String PUBLIC_FINAL_STATIC_NAME = "123";
static final List<String> PUBLIC_FINAL_STATIC_NAMES = Arrays.asList("123", "234");
public final List<String> publicFinalNames = Arrays.asList("123", "234");
使可变性最小化
不可变类是指其实例不能被修改的类,除非一定要可变,否则都应该是不可变的
域除非一定要变,否则有设为final,不要为每个get方法编写一个set方法
复合优先于继承
继承打破了封闭性
复合:增加一个私有域,引用现有类的一个实例。对应设计模式中装饰器模式和代理模式
package codeTemplate.effectiveJava.bean;
import java.util.List;
public class BasicBean {
private String name;
private List<String> functions;
public BasicBean(String name, List<String> functions) {
this.name = name;
this.functions = functions;
}
public void addFunction(String function) {
this.functions.add(function);
}
}
继承
package codeTemplate.effectiveJava.bean;
import java.util.List;
public class RedBean extends BasicBean {
private int number = 0;
public RedBean(String name, List<String> function) {
super(name, function);
}
@Override
public void addFunction(String function) {
number++;
super.addFunction(function);
}
}
复合
package codeTemplate.effectiveJava.bean;
public class YellowBean {
private int number = 0;
private final BasicBean basicBean;
public YellowBean(BasicBean basicBean) {
this.basicBean = basicBean;
}
public void addFunction(String function) {
number++;
basicBean.addFunction(function);
}
}
要么设计继承并提供文档说明,要么禁止继承
接口优于抽象类
接口使得安全地增强类的功能成为可能
为接口提供一个抽象的骨架实现类(抽象类),即模板方法模式
接口只用于定义类型
常量接口模式是对接口的不良使用,应使用不可实例化额工具类,静态导入
常量接口
package codeTemplate.effectiveJava.bean;
public interface Consts {
String BOOK_NAME = "asds";
}
不可实例化的工具类
package codeTemplate.effectiveJava.bean;
public class Constants {
private Constants() {
}
public static final String BOOK_NAME = "asds";
}
类层次优于标签类
使用继承生成多个类,优于多个构造器生成不同的对象
静态成员类(内部类)优于非静态成员类
嵌套类存在的目的应该只是为它的外围类提供服务
永远不要将多个顶级类或者接口放在一个源文件中
顶级类:非成员类(内部类)