Effective Java

1. 考虑用静态工厂方法代替构造函数
    静态工厂方法优点:具有名字;每次调用时,不要求必须创建新对象;可以返回对象。
    实质就是静态方法,可以方便的调用。缺点是不能被实例化。

//定义静态方法   
Public class StaticTest {   
    public static String getResults(String name) {   
        return name;   
    }   
}   
  
//调用   
String name = StaticTest.getResults("tingor"); 

   

    服务提供框架: 有一个Properties文件,每个Key对应一个Class,框架用来注册一个类,然后实例化。

public abstract class Foo {
    private static Map implementations = null;
    private static synchronized void initMapIfNecessary() {
        if (implementations == null)
            implementations = new HashMap();
    }
    public static Foo getInstance(String key) {
        initMapIfNecessary();
        Class c = (Class) implementations.get(key);
        if (c == null)
            return new DefaultFoo();
        try {
            return (Foo) c.newInstance();
        } catch (Exception e) {
            return new DefaultFoo();
        }
    }
    public static void main(String[] args) {
        System.out.println(getInstance("NonexistFoo"));
    }
}

public class DefaultFoo extends Foo {}

  

 

2. 使用私有构造函数强化Singleton属性

    singleton只能被实例化一次,通常用来代表唯一性的系统组件。

方法一: 饥饿加载 - 性能稍微优先
public class Singleton() {
    public static final MySingleton instance = new MySingleton();
    private Singleton() {}
    public static MySingleton getInstance() {
        return INSTANCE;
    }
}

方法二: 懒加载
public class Singleton {   
    private static Singleton instance = null;   
    private Singleton() {}   
    public synchronized static Singleton getInstance() {   
        if (instance == null) {   
            instance = new Singleton();   
        }   
        return instance;   
    }   
}  

为了维护singleton性,在序列化的时候需要提供一个readResolve方法,以便对象在反序列化的时候,会创建一个新的实例
public class Singleton() {
    public static final Singleton instance = new MySingleton();
    private MySingleton() {}
    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}

 

 

3. 通过私有构造函数强化不可实例化的能力

    不能实例化一个类,一般用于工具类的范围。 

public class UtilityClass {
    private UtilityClass() {}
}

 

 

4. 避免创建重复的对象

    4.1 不要重复创建同一个对象 

String s = new String("silly");  //Don't do this
String s = "silly";  //should do this

 

    4.2 把只需要创建一次的局部变量变成final静态域

//错误做法(每次isBabyBoomer被调用的时候,都会创建Calendar和TimeZone,以及两个Date实例)

public class Person {
    private final Date birthDate;
    public Person(Date birthDate) {
        this.birthDate = birthDate; 
    }
    public boolean isBabyBoomer() {
        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
        Date boomStart = gmtCal.getTime();
        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
        Date boomEnd = gmtCal.getTime();
        return birthDate.compareTo(boomStart) >=0 && birthDate.compareTo(boomEnd) < 0;
    }
}

//改进之后
public class Person {
    private final Date birthDate;
    public Person(Date birthDate) {
        this.birthDate = birthDate; 
    }
    private static final Date BOOM_START;
    private static final Date BOOM_END;
    static {
        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
        Date boomStart = gmtCal.getTime();
        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
        Date boomEnd = gmtCal.getTime();
    }
    public boolean isBabyBoomer() {
        return birthDate.compareTo(boomStart) >=0 && birthDate.compareTo(boomEnd) < 0;
    }
}

 

 

5. 消除过期的对象引用

    如果对象一直不被回收,那么很容易引起OutOfMemoryError的错误。

//Stack中,先增长,然后收缩,那么从栈弹出的对象将不会被回收;另一个例子在缓存,解决的办法是使用WeakHashMap
public class Stack {
    private Object[] elements;
    private int size = 0;
    public Stack(int initialCapacity) {
        this.elements = new Object[initialCapacity];
    }
    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }
    public Object pop() {
        if (size == 0) throw new EmptyStackException();
        return elements[--size];
    }
    private void ensureCapacity() {
        if (elements.length == size) {
            Object[] oldElements = elements;
            elements = new Object[2 * elements.length + 1];
            System.arraycopy(oldElements, 0, elements, 0, size);
        }
    }
}

//pop方法修改版本
public Object pop() {
    if (size == 0) throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null;  //消除旧的引用
    return result;
}

 

 

6. 避免使用终结函数

    6.1 终结函数并不能保证能够执行,如果非要使用,那么首要考虑显示终止方法

Foo foo = new Foo(...);
try {
    //Do what mush be done with foo
} finally {
    foo.terminate();  //foo自带的外在终止方法,还有例如数据库的关闭连接方法
}

 

    6.2 如果一类有一个终结函数,并且一个子类改写了终结函数,那么子类的终结函数必须要调用父类的终结函数

protected void finalize() throws Throwable {
    try {
        //Finalize subclass state
    } finally {
        super.finalize();
    }
}

 

    6.3 如果一个子类改写了超类的终结函数,但忘了手工调用超类的终结函数,那么使用终结函数守卫者(finalizer guardian)来实现其终结,注意该终结函数放在一个匿名的类中 

public class Foo {
    private final Object finalizerGuardian = new Object() {
        protected void finalize() throws Throwable {
            //finalize outer Foo object
        }
    }
}

 

 

7. 在改写equals的时候请遵守通用约定
    当一个类有自己特有的逻辑相等原则,而超类也没有改写,则需要改写Object.equals
    自反性:x.equals(x)一定为true
    对称性:y.equals(x)返回true, x.equals(y)一定也为true
    传递性:x.equals(y)为true,y.equals(z)为true,那么x.equals(z)一定为true
    一致性:多次调用x.equals(y)要么一直返回true,要么一致返回false
    非空性:非空x,x.equals(null)一定返回false

public boolean equals(Obejct otherObject) {
    if (this == otherObject) return true; //检测this与otherObject是否引用同一个对象
    if (otherObject == null) return false; //检测otherObject是否为null
    if (getClass() != otherObject.getClass)   
        return false; //比较this与otherObject是否属于同一个类 
    if (!otherObject instanceof thisClass)
        return false; //该方法可以替代上一行判断   
    Employee other = (Employee)otherObject; //将otherObject转换为相应的类型 
    return name.equals(other.name) && salary == other.salary; //对所有域进行比较
}

  

 

8. 改写equals时总是要改写hashCode

private volatile int hashCode = 0;  //延迟初始化
public int hashCode() {
    if (hashCode == 0) {
        int result = 17;
        result = 37 * result + areaCode;
    }
    return hashCode;
}

 

 

9. 总是要改写toString
    主要用于输出的程序便于调试

public String toString() {
    return getClass().getName() + "[name=" + name + ",salary=" + 
        salary + ",hireDay=" + hireDay + "]";
} 

 

 

10. 谨慎地改写clone

    对于该条目,我认为最好不使用clone方法。

 

 

11. 考虑实现Comparable接口

    compareTo方法允许简单的相等比较,也允许执行顺序比较,一般用于Arrays等数据结构

    Arrays.sort(a);

 

 

12. 使类和成员的可访问能力最小化

    好的设计,应该隐藏内部数据和具体细节

 

 

13. 支持非可变性

    例如: String,BigInteger都是非可变类

    非可变类,实例不能被修改,遵循5条规则
    不要提供修改对象的方法
    保证没有子类改写的方法
    使所有的域都是final
    使所有的域都成为私有的
    保证对于可变组件的互斥访问

    非可变对象本质上是安全的,所以不要求同步,这样类定义为final,就可以被多个线程共享

 

 

14. 复合优先于继承

    包装类即装饰器的使用

 

 

15. 要么专门为继承而设计,并给出文档说明,要么禁止继承

 

 

16. 接口优于接口类

 

 

17. 接口只是被用于定义类型

    在接口中,最好不要定义常量

 

 

18. 优先考虑静态成员类

    声明的成员类不要求访问外围实例,那么应该加入static修饰符

    嵌套类: 静态成员类,非静态成员类,匿名类,局部类

 

 

19. 用类代替结构

 

 

20. 用类层次代替联合

 

 

21. 用类代替enum结构

    在Java5中,又加入了enum这种结构

//类型安全枚举
public class Suit {
    private final String name;
    private Suit(String name) {
        this.name = name;
    }
    public String toString() {
        return name;
    }
    public static final Suit CLUBS = new Suit("clubs");
    public static final Suit DIAMONDS = new Suit("diamonds");
    public static final Suit HEARTS = new Suit("hearts");
    public static final Suit SPADES = new Suit("spades");
}

 

 

22. 用类和接口来代替函数指针

 

 

23. 检查参数的有效性

    应该在抛出空指针或者其他不可获知异常之前,进行参数检查

public BigInteger mod(BigInteger m) {
    if (m.signum() <= 0) 
        throw new ArithmenticException("Modulus not positive");
}

 

 

24. 需要时使用保护性拷贝

//原始类
public final class Period {
    private final Date start;
    private final Date end;
    public Period(Date start, Date end) {
        if (start.compartTo(end) > 0)
            throw new IllegalArgumentException(start + " after " + end);
        this.start = start;
        this.end = end;
    }
    public Date start() {
        return start;
    }
    public Date end() {
        return end;
    }
}

//修改Date
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78); //已经修改了时间

//重构之后的类
public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
    if (start.compartTo(end) > 0)
        throw new IllegalArgumentException(start + " after " + end);
}
public Date start() {
    return (Date)start.clone();
}
public Date end() {
    return (Date)end.clone();
}

 

 

25. 谨慎设计方法的原型

    谨慎选择方法的名字
    不要过于追求提供便利的方法
    避免长长的参数列表(一般为3个): 有两个方法来避免:把一个方法分解成多个方法;创建辅助类
    对于参数类型,优先使用接口而不是类
    谨慎使用函数对象

 

 

26. 谨慎使用重载

 

 

27. 返回零长度数组而不是null

 

 

28. 为所有导出的API元素编写文档注释

 

 

29. 将局部变量的作用域最小化
    局部变量应该在第一次使用它的地方声明,而不要过早在前面声明
    如果循环终止后循环变量不再需要,那么for循环应该优先于while循

 

 

30. 了解和使用库
    java.lang,java.util,java.io

 

 

31. 如果要求精确的答案,请避免使用float和double
    尤为不合适货币计算,可以考虑BigDecimal

 

 

32. 如果其他类型更合适,则尽量避免使用字符串

 

 

33. 了解字符串连接的性能
    使用StringBuffer或者StringBuilder代替

 

 

34. 通过接口引用对象
    List subscribers = new ArrayList();
    如果没有接口,那么就用基类来引用

 

 

35. 接口优于反射机制

 

 

36. 谨慎地使用本地方法

 

 

37. 谨慎地进行优化
    努力避免那些限制性能的设计决定,考虑你的API设计决定的性能后果

 

 

38. 遵守普遍接受的命名惯例

 

 

39. 只针对不正常的条件才使用异常

 

40. 对于可恢复的条件使用被检查的异常,对于程序错误使用运行时异常

 

 

41. 避免不必要地使用被检查的异常

 

 

42. 尽量使用标准的异常
    IllegalArgumentException: 参数的值不合适
    IllegalStateException: 对于这个方法调用而言,对象状态不合适
    NullPointerException: 在null被禁止的情况下参数值为null
    IndexOutOfBoundException: 下标越界
    ConcurrentModificationException: 在禁止并发修改的情况下,对象检测到并发修改
    UnsupportOerationException: 对象不支持客户请求的方法

 

 

43. 抛出的异常要适合于相应的抽象
    可以把异常进行包装,转译成容易理解的异常

 

 

44. 每个方法抛出的异常都要有文档

 

 

45. 在细节消息中包含失败-捕获异常
    可以在异常中加入失败的消息,关键字符

 

 

46. 努力使失败保持原子性

//在其他动作之前,就进行size检查
public Object pop() {   
    if (size == 0) 
        throw new EmptyStackException();   
    Object result = elements[--size];   
    elements[size] = null;  //消除旧的引用   
    return result;   
}  

 

 

47. 不要忽略异常

 

 

48. 对共享可变数据的同步访问

 

 

49. 避免过多的同步

 

 

50. 永远不要在循环的外面调用wait
    一般使用notifyAll()

 

 

51. 不要依赖于线程调度器

 

 

52. 线程安全性的文档化

 

 

53. 避免使用线程组

 

 

54. 谨慎地实现Serializable
    实现了Serializable的代价是,一旦一个类发布,改变这个类的实现的灵活性将降低
    为了继承而设计的类和内部类应该很少实现Serializable

 

 

55. 考虑使用自定义的序列化形式

 

 

56. 保护性地编写readObject方法

 

 

57. 必要时提供一个readResolve
    对于Singleton需要 

平衡电桥在高压绝缘检测中的动态切换策略与误差优化 本文深入探讨了平衡电桥在高压绝缘检测中的动态切换策略与误差优化方法。通过分析四种基本切换模式及智能切换时序设计,显著提升检测精度与范围。结合电阻选型黄金法则和软件补偿技术,有效降低测量误差,为电动汽车电池管理系统提供可靠的安全保障。 阅读详情

相关推荐

用PyTorch手把手搭建液态神经网络(LNN):从微分方程到无人机避障实战

本文详细介绍了如何使用PyTorch搭建液态神经网络(LNN),从微分方程基础到无人机避障实战应用。LNN通过动态时序建模和微分方程实现高效计算,特别适合多传感器数据融合场景。文章包含完整的代码实现、训练技巧及性能优化方案,帮助开发者快速掌握这一前沿技术。

uber9的博客 439

Effective Java 第三版 中文翻译

effective-java-third-edition 介绍 Effective Java 第三版全文翻译,纯属个人业余翻译,不合理的地方,望指正,感激不尽! 目录 推荐序 前言 致谢 第一章 引言 第二章 创建和销毁对象   本章涉及创建和销毁对象,包括何时以及如何创建它们,何时以及如何避免创建它们,如何确保它们被及时销毁,以及如何管理在销毁之前必须进行的清理操作。 第1项:考虑静态工...

Coloured_Glaze的博客 3861

MODBUS通讯不求人:手把手教你用三菱FX2N控制士林变频器

本文详细介绍了如何使用三菱FX2N PLC通过MODBUS协议控制士林变频器,涵盖硬件连接、参数配置、程序设计及通讯优化等关键步骤。特别针对没有内置MODBUS函数块的老款PLC,提供了CRC校验和稳定数据交换的实用解决方案,帮助工程师快速实现工业自动化设备的高效通讯。

v4w5x6的博客 226

Effective Java 总结

前言读完了Effective Java,对这本书总结一下,结合自己在实际中的使用,这里只记录部分我觉得重点的点,顺便加上自己平时注意到的点一、对象创建和销毁1:考虑用静态工厂方法替换构造器静态工厂方法的惯用名称:valueOf——该方法返回的实例与它的参数具有相同的值,实际上是类型转换方法; getInstance——返回的实例是通过方法的参数来描述的,对于单例模式(Singleton)来说,该方

XXX 1万+

rv1106 模型部署

ONNX(Open Neural Network Exchange),开放神经网络交换,是一种模型IR,用于在各种深度学习训练和推理框架转换的一个中间表示格式,支持多种深度学习框架,包括 TensorFlow、PyTorch、Caffe 等。将模型转换为 ONNX 格式后,可以更容易地在不同的深度学习框架中进行部署和推理,而无需重新训练模型。

weixin_50993868的博客 1286

战舰V3移植CANopenNode并驱动电机全流程

第三部分是电机的对象字典(也就是节点的OD)中的索引,长度2个字节。索引发送的是小段模式,比如这一部分为0X40 0X60,实际操作的索引地址为0X6040。第一部分是COB-ID,长度1个字节,电机的node-ID默认为0x01,所以报文ID一直是601。第五部分是要写入的数据,数据发送的时候是小端模式,低字节数据先发送,长度由第二部分决定。配置定时器6,时间为1ms,根据公式计算得到参数PSC取72-1,ARR取1000-1。第二部分是CMD,长度1个字节,其实就是数据部分的长度,

qq_50526837的博客 3045

Effective Java, Third Edition

https://github.com/jbloch/effective-java-3e-source-code 网址是 Effetive java的源码 effective-java-3e-source-code 转载于:https://www.cnblogs.com/qxyy/p/9606873.html

anjieqing1102的博客 258

关节电机技术全解析:原理、双编码器、控制方法与硬件选型

关于关机电机的组成,技术原理,特点以及选型等方面的详细介绍,可以帮助快速学习关节电机相关内容!

start_up_go的博客 692

Effective Java阅读心得

最近再次拜读了Effective Java一书,确实很有感悟,第一次读的时候我的java基础还很不牢,代码积累也不多,读起来总是云里雾里,而这一次读的时候,确实有很多共鸣,感悟,在书上自己写了一些心得体会,俗话说好记性不如烂笔头,也记录到博客里,有需要的时候可以查阅一下第一章  引言引言部分就没啥说的了,就是介绍一下本书第二章  创建和销毁对象第一条:考虑用静态工厂方法代替构造器其实这里指的静态工...

Qunter的博客 2397

西南科技大学数字电子技术实验七(4行串行累加器设计及FPGA实现)FPGA部分

/在k=1时输入1,并在k=0时运算。//在k=1时输入0,并在k=0时运算。//在k=1时输入1,并在k=0时运算。//在k=1时输入0,并在k=0时运算。//在k=1时输入1,并在k=0时运算。//在k=1时输入1,并在k=0时运算。//在k=1时输入0,并在k=0时运算。//在k=1时输入0,并在k=0时运算。三、程序清单(每条语句必须包括注释或在开发窗口注释后截图)四、综合、管脚分配、生成输出文件、下载(所有步骤截图)五、仿真程序清单、波形(波形截图必做,截图!.k(k),//开关。

Welcome To My6n Blog 4332

【CANoe示例分析】SOMEIPWithvCDL_16

本示例来源于官方提供的示例工程:0004_基于vCDL实现SOMEIP通信_Demo\0004_基于vCDL实现SOMEIP通信_Demo\SOMEIPWithvCDL。

jasonj333 567

一. 初识Effective Java

这几天看了Effective Java,感觉这本书中讲解的Java中的一些方面帮助我们更深的理解Java,学习Java,所以决定把里面我觉得重要的点 记再这里。 第一章,简单通俗地讲到本书中大多数条目是通过程序示例进行说明。 许多的代码示例说明了 许多设计模式 和 习惯用法,还会有设计模式和习惯用法交叉引用。 1.代码规则:清晰性和简洁性最为重要; 模块的用户不应该被模块的行为...

Jason_LH1024的博客 290

ARM系统控制和管理接口System Control and Management Interface

本文档描述了一个可扩展的独立于操作系统的软件接口,用于执行各种系统控制和管理任务,包括电源和性能管理。 本文档描述了系统控制和管理接口(SCMI),它是一组操作系统无关的软件接口,用于系统管理。

AI-安全-功耗 1913

effective java网址

2020年12月31日: 准备看些编程类的书籍: effective java :https://cl0610.github.io/effective-java-learning/

mingyuli的博客 188

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

《Effective java》第二版阅读笔记

18.接口优于抽象类 接口和抽象类都是java中定义类型、扩展功能的机制。 两者主要区别在于接口中全部是抽象方法,抽象类中可以包含抽象方法,也可以包含非抽象方法。 而接口优于抽象类的原因是,类可以实现多个接口,但只能继承一个抽象类,抽象类的使用受限。 假使对一个类进行扩展功能,可在implements后新增接口实现,如Comparable引进到java中后,更新了许多现有类。同时接口也是mixin...

张晨雪的博客 664

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

《Effective Java》笔记

《Effective Java》笔记以前看书时记的笔记,分享一下。1 创建和销毁对象1.1 考虑用静态工厂方法代替构造函数静态工厂方法相比于构造函数的优点: 1、具有名字,从而易于阅读; 2、每次调用时不要求非得创建一个新的对象(如Singleton); 3、可以返回一个原返回类型的子类型对象; 缺点: 1、如果不含公有的或者受保护的构造函数,就不能被子类化 2、静态工

渔歌唱晚 1168

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

《Effective Java2》笔录

转自:http://www.verydemo.com/demo_c89_i134810.html Joshua Bloch在国内出版的书包括《Effective Java2》《Java Puzzlers》《Java Concurrency in Practive》(合著)。特别...

chenghuo9876的博客 189

Effective Java第三版有哪些新功能?

自从听说即将出版的有效Java 第三版以来,我一直想知道其中有什么新内容。 我假设将涵盖自Java 6以来引入Java的功能,的确如此。 但是,第三版Java开发人员经典版也有一些其他更改。 在本文中,我提供了有关在第三版中添加,更改或删除的主题的高级概述。 在列出我所观察到的似乎是《 有效Java第三版》中的新内容之前,我需要做出免责声明,说我很可能会错过本书中的几处更改,共有12章,...

最佳 Java 编程 518

effective java(一)

文章目录effective java(一)第一条:用静态工厂方法代替构造器优势缺点第二条:遇到多个构造器参数时要考虑使用构建器第三条:用私有构造器或者枚举类型强化Singleton属性 effective java(一) 本系列内容是学习effective java的理解和笔记。有一些内容在初次阅读的时候理解不深刻,或者完全不理解。因此先把内容要点记录下来,后续可以不断回顾这些笔记的内容,和多次查...

qq_22343953的博客 544

Effective Java精髓

Effective Java  第一章:创建和销毁对象 1. 使用静态工厂方法 ——优点:1. 可以提供多种方式的方法签名。                   2. 不必每次都返回一个新的实例。                    3. 可以返回本类的一个子类实例。                   4. 使用静态类型推导:public static &lt;k,v&gt; Ha...

仙路看近行远 608

《Effective Java(第三版)》笔记

本文提供了《Effective Java》第3版的思维导图和相关资源链接。思维导图分为三部分,分别对应第1-4章、第5-8章和第9-12章的内容,帮助读者快速梳理和掌握书中的核心知识点。此外,文章还提供了该书的源码链接,方便读者深入学习和实践。这些资源为Java开发者提供了高效的学习工具,助力提升编程技能。

千里之行,始于足下 606

Effective Java 学习资源

Effective Java 学习资源 去发现同类优质开源项目:https://gitcode.com/ 欢迎来到Effective Java资源仓库!这里为您提供了《Effective Java》的PDF版本书籍,旨在帮助Java开发者提高编程技能,写出更高效、更可靠的代码。 简介 《Effective Java》是一本由Joshua Bloch编写的经典Java编程书籍,它详细介绍了Java编...

gitblog_06796的博客 303

Effective Java 78条军规

Effective Java, 2nd Edition by Joshua Bloch I, Michael Parker, own this book and took these notes to further my own learning. If you enjoy these notes, please purchase the book! Chapter

Bitcoin学习中,欢迎吐槽 1898

Effective Java(第3版)总结

创建和销毁对象 1、用静态工厂方法代替构造器 2、遇到多个构造器参数时要考虑使用构建器 3、用私有构造器或者枚举类型强化Singleton属性 4、通过私有构造器强化不可实例化的能力 5、优先考虑依赖注入来引用资源 6、避免创建不必要的对象 7、消除过期的对象引用 8、避免使用终结方法和清除方法 9、try-with-resources优先于try-finally 对于所有对象都通用的方法 10、覆盖equals时请遵守通用约定 11、覆盖equals时总要覆盖hashCode 12、始终要覆盖toStr.

chenjingwo4的博客 485

effective java

        今天了解了一下Java四大名著之一的《Effective Java》,读了一下作者Joshua Bloch的序言颇有感触。下面引用一下作者经典原文:       “如果曾经学习过第二种语言,并尝试在课堂之外使用这种语言,那么你该知道有三件事情是必须要掌握的:这门语言的结构如何(语法).如何命名你想谈论的事物(词汇),以及如何用习惯和高效的方式来表达事情(用法).在课堂上通常只是涉及...

灰色影子 152

effective java 第三版 builder建造者 P12

package Effective02.P12; import java.util.EnumSet; import java.util.Objects; import java.util.Set; public abstract class Pizza { public enum Topping{ HAM, MUSHROOM, ONION,PEPPER, SAUSAG...

absolute_chen的博客 345
上一篇: Head First Design Patterns
下一篇: MiniTomcat - How Tomcat Works 1: HttpServer
book_overkill
博客等级 码龄20年 1粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值