JAVA
文章平均质量分 68
Mr.菜园子
欢迎关注,如想查看新篇,请关注我个人的博客吧:www.sddzcyz.cn
展开
-
Linux环境(CentOS7)下使用yum安装JDK1.8
Linux环境(CentOS7)下使用yum安装JDK1.8原创 2022-08-24 21:55:10 · 1219 阅读 · 0 评论 -
Effective Java 返回零长度的数组或者集合,而不是null
private final List<Cheese> cheesesInStock = ...;public Cheese[] getCheese() { if(cheesesInStock.size() == 0) return null; ...}如果返回null,在客户端处理代码就需要有额外的代码来处理null返回值:Cheese[] cheeses = shop.getCheeses();if(cheeses != null &am.原创 2021-03-14 21:00:58 · 148 阅读 · 0 评论 -
Effective Java 慎用可变参数
Java 1.5增加可变参数方法,可变参数方法接受0个或者多个指定类型的参数。可变参数的机制通过先创建一个数组,数组的大小为在调用位置所传递的参数数量,然后将参数值传到数组中,最后将数组传递给方法。static int sum(int... args) { int sum=0; for(int arg : args) sum += arg; return sum;}该方法如期望的那样,sum()=0,sum(1,2,3)=6有时候...原创 2021-03-13 22:55:09 · 216 阅读 · 0 评论 -
Effective java 慎用重载
试图根据一个集合是Set、Liist、还是其他的集合类型,对它进行分类的程序:public class CollectionClassifier { public static String classify(Set<?> s) { return "Set"; } public static String classify(List<?> l) { return "List"; } public st.原创 2021-03-10 23:16:52 · 118 阅读 · 0 评论 -
Effective Java 谨慎设计方法签名
1.谨慎地选择方法的名称。遵循标准的命名习惯。2.不过于追求提供便利的方法。方法太多会使类难以学习、使用、文档化、测试和维护。3.避免过长的参数列表。目标是四个参数以下。缩短参数列表的方法:(1)把方法分解成多个方法,可能会导致方法过多, 通过提升方法正交性,可以减少方法数目。java.util.List接口,它没有提供在子列表中查找元素第一个索引和最后一个索引的方法,这个两个方法需要三个参数,它提供了subList方法,需要两个参数,还有indexOf和lastIndexOf方法,需要一个原创 2021-03-09 22:10:38 · 114 阅读 · 0 评论 -
Effective Java 必要时进行保护性拷贝
不是“把内存当做一个巨大的数组来看待”,Java不会破坏内存。编写面对客户的不良行为时仍能保持健壮性的类,是非常值得投入时间的。不可变类的构造函数上面的类不是不可变类,因为Date类本身是可变的。p对象的end对象已经被改变了。不可变类的构造函数如何实现对于构造函数的每个可变参数进行保护性拷贝(defensive copy),并且使用备份对象作为Period实例的组件,而不使用原始的对象。保护性拷贝是在检查参数的有效性之前进行的,并且有效性检查是针对拷贝之后的对象,而原创 2021-03-07 20:34:42 · 180 阅读 · 2 评论 -
Effective Java 检查参数的有效性
绝大多数方法和构造器对于传递给他们的参数值都会有某些限制。例如索引值必须是非负数,对象引用不能为null,等等。应该在文档中清楚地指明所有这些限制,并且在方法体的开头出检查参数,以强制施加这些限制。这是“应该在发生错误之后尽快检测出错误”这一普遍原则的一个具体情形。如果传递无效的参数值给方法,这个方法在执行之前先对参数进行了检查,那么它很快就会失败,并且清楚的抛出适当的异常。如果没有检查它的参数就有可能发生几种情况。该方法可能在处理过程中失败,并且产生令人费解的异常。更糟糕的是,该方法可以正原创 2021-03-06 10:54:24 · 133 阅读 · 0 评论 -
Effective Java 用标记接口定义接口类型
标记接口(marker interface) 是没有包含方法声明的接口,而只是指明(或者“标明”)一个类实现了具有某种属性的接口。例如,考虑Serilizable接口(第12章)。通过实现这个接口,表明类的实例可以被写到ObjectOutputStream(或者“被序列化”)。 你可能听说过标记注解(第39项)使得标记接口过时了。这种断言是不准确的。标记接口有两点胜过标记注解。首先,也是最重要的一点,标记接口定义的类型是由被标记类的实例实现的;标记注解则没有定义这样的类型。 标记接口类型的存在允许你在原创 2021-03-04 22:49:50 · 107 阅读 · 1 评论 -
Effective Java 坚持使用Override注解
1.简介Override注解只能用在方法声明中,表示被注解的方法声明覆盖了超类型中的一个声明。2.使用Override注解的好处当你想要覆盖父类的方法时,却因为人为原因将覆盖写成了重载,如果在方法上标注了Override注解,那么编译器就会在编译期间帮助你发现这个错误,而非在程序运行时出现非法的错误。例如,以下例子没有覆盖Object类的equals方法,而是重载了,所以出现不合预期的错误:public class App { private final String name;..原创 2021-03-03 22:57:07 · 116 阅读 · 1 评论 -
Effecitve Java 注解优先于命名模式
Java 1.5之前,一般使用命名模式表明有些程序元素需要通过某种工具或者框架进行特殊处理。例如,JUnit测试框架原本要求用户一定要用test作为测试方法名称的开头。命名模式的缺点:1.文字拼写错误导致失败,测试方法没有执行,也没有报错 2.无法确保它们只用于相应的程序元素上,如希望一个类的所有方法被测试,把类命名为test开头,但JUnit不支持类级的测试,只在test开头的方法中生效 3.没有提供将参数值与程序元素关联起来的好方法。注解能解决命名模式存在的问题,下面定义一个注解类型指定..原创 2021-03-02 23:07:27 · 109 阅读 · 0 评论 -
用EnumMap代替序数索引
有时候,会见到利用ordinal方法来索引数组的代码。例如下面这个简化的类,表示一种烹饪用的香草:public class Herb { public enum Type { ANNUAL, PERENNIAL, BIENNIAL } private final String name; private final Type type; Herb(String name, Type type) { this.name = name; th原创 2021-02-26 21:58:38 · 162 阅读 · 0 评论 -
Effective Java(用实例域代替序数、用EnumSet代替位域)
1.用实例域代替序数枚举类型有一个ordinal方法,它的范围是常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用实例域,例如:public enum ErrorCode { FAILURE(0), SUCCESS(1); private final int code; //上一条讲到枚举天生不可变,所有域都应该是final的。 ErrorCode(int code) { this.code = code原创 2021-02-24 20:24:03 · 127 阅读 · 0 评论 -
Effective Java 用enum代替int常量
在java1.5之前,表示枚举类型的常用模式是声明一组具名的int常量,每个类型成员一个常量:public static final int APPLE_FUJI = 0;public static final int APPLE_PIPPIN = 1;public static final int APPLE_GRANNY_SMITH = 2;public static final int ORANGE_NAVEL = 0;public static final int ORANGE_原创 2021-02-23 21:23:12 · 138 阅读 · 0 评论 -
Effective java 优先考虑类型安全的异构容器
泛型最常用于集合,如Set和Map<K, V>,以及单元素容器,例如ThreadLocal 和AtomicReference 。在这些用法中,它都充当被参数化了的容器。这样就限制你没个容器只能有固定数目的类型参数。一般来说,这种情况正是你想要的。一个Set只有一个类型参数,表示它的元素类型;一个Map有两个类型参数,表示它的键和值类型;诸如此类。 但是,有时候你会需要更多的灵活性。例如,数据库行可以有任意多的列,如果能以类型安全的方式访问所有列就好了。幸运的是,有一种方法可以很容易地做到这原创 2021-02-22 22:34:00 · 115 阅读 · 0 评论 -
Effective Java 利用有限制通配符来提升API的灵活性
如第28条所述,参数化类型是 不可变的(invariant)。对两个不同类型T1和T2而言,List<T1>与List<T2>没有父子类型关系。1、Extends有时候,需要的灵活性要比不可变类型所能提供的更多。考虑第26条中的堆栈下面就是他的公共API:public class Stack<E> {public Stack();public void push(E e);public E pop();public boolean isEmpt原创 2021-02-18 22:06:30 · 91 阅读 · 0 评论 -
Effective Java 优先考虑泛型
一般来说参数化声明并使用JDK提供的泛型和方法通常并不困难。编写自己的泛型会比较困难一些,但是值得花些时间去学习如何编写。 考虑到第7项中这个简单(玩具)堆栈的实现:// Object-based collection - a prime candidate for genericspublic class Stack { private Object[] elements; private int size = 0; private static final int原创 2021-01-07 20:35:41 · 150 阅读 · 0 评论 -
Effective Java 优先考虑泛型方法
就如类可以从泛型中受益一般,方法也可以。静态工具方法尤其适合与泛型化。JDK中的Collections泛型中的所有“算法”方法都泛型化了。如:下面这个方法返回连个集合的联合。public static Set union(Set s1,Set s2){ Set result = new HashSet(s1); result.addAll(s2); return result;}为了方法变成类型安全的,要将方法声明修改为声明一个类型...原创 2021-01-05 21:26:39 · 117 阅读 · 0 评论 -
Effective java 列表优先于数组
看到这个标题的时候,我有个疑惑:是不是优先使用列表,能用列表就尽量用列表吗?我觉得,之所以说列表优于数组,应该是在某些语法设计方面,列表有比较大的优势。但是要具体问题具体分析,数组也有自身的优势(对于固定长度的序列,性能更加高),而且在某些情况下,列表的所谓的优势并不能发挥。数组是协变且可以具体化的;泛型是不可变的且可以被擦除的(不可具体化的)。**协变与不可变类型数组是协变类型,指继承关系的。泛型是不可变类型(也就是final类型),没有继承关系。无限制通配符类型是一个特例。//这段原创 2021-01-03 18:48:15 · 143 阅读 · 0 评论 -
Effective Java 消除非受检警告
使用泛型编程时,会遇到许多编译器警告,如:非受检强制转化警告,非受检方法调用警告,非受检普通数组创建警告,非受检转换警告。当你越来越熟悉泛型之后,遇到的警告也会越来越少,但是不要期待从一开始用泛型编写代码就可以正确的进行编译。PS:非受检警告就是代码上黄色的感叹号 有许多非受检警告很容易消除,例如:——HashSet是一个原始类型。泛型类型的引用HashSet < E >应该是参数化的——局部变量的值不使用exaltation1-类型安全:表达式类型的HashS...原创 2021-01-03 10:44:18 · 122 阅读 · 0 评论 -
Effective Java 请不要在新代码中使用原生态类型
声明中具有一个或者多个类型参数(type parameter)的类或者接口,就是泛型。泛型类和泛型接口统称为泛型(generic type)。每种泛型定义一组参数化的类型,构成格式为:先是类或者接口的名称,接着用尖括号(<>)把对应于泛型形式类型参数的实际类型参数列表括起来。原生态类型就像从类型声明中删除了所有的泛型信息一样。实际上,原生态类型List与Java平台没有泛型之前的接口类型List完全一样。如果不提供类型参数,只是使用集合类型和其他泛型的原生态类型仍然是合法的,但是原创 2021-01-03 10:29:57 · 102 阅读 · 0 评论 -
Effective Java 优先考虑静态成员类
嵌套类指被定义在一个类的内部的类。嵌套类存在的目的应该只是为它的外围类提供服务。如果嵌套类将来可能用于其他环境,它应该是顶层类。嵌套类有四种:静态成员类,非静态成员类,匿名类,局部类。静态成员类的常见用法是作为公有的辅助类,仅当与外部类一起使用才有意义,考虑一个枚举,它描述计算器支持的各种操作,Operation枚举应该是Caculator类的公有静态成员类,然后就可以使用如Caculator.Operation.PLUS这样的名称来引用这些操作。非静态成员类的每个实例都隐含与...原创 2021-01-02 19:57:02 · 90 阅读 · 0 评论 -
Effective Java 用函数对象表示策略
有些语言支持函数指针(function pointer)、代理(delegate)、lambda表达式(lambda expression),或者支持类似的机制,允许程序把“调用特殊函数能力”存储起来并传递这种能力。这种机制通常用于允许函数的调用者通过传入第二个函数,来指定自己的行为。例如,C语言标准库中的qsort函数要求用一个指向comparator(比较器)函数的指针作为参数,它用这个函数来比较待排序的元素。比较器函数有两个参数,都是指向元素的指针。如果第一个参数所指的元素小于第二个参数所指的元素,则原创 2021-01-02 19:46:19 · 98 阅读 · 0 评论 -
Effective Java 类层次优于标签类
有时候,可能会遇到带有两种甚至更多风格的实例代码的类,并包含表示实例风格的标签(tag)域。例如,考虑下面这个类,它能够表示圆形或者矩形:// Tagged class - vastly inferior to a class hierarchy!class Figure{ enum Shape{RECTANGLE,CIRCLE}; //Tag field - the shape of this figure final Shape shape; //There field are原创 2021-01-02 19:35:17 · 108 阅读 · 0 评论 -
Effective Java 接口只用于定义类型
当类实现接口时,接口就充可以引用这个类的实例的类型。因此,类实现了接口,就表明客户端可以对这个类的实例实施某些动作。为了任何其他目的而定义接口是不恰当的。有一种接口被称为常量接口(constant interface),它不满足上面的条件。这种接口没有包含任何方法,它只包含静态的final域,每个域都导出一个常量。使用这些常量的类实现这个接口,以避免用类名来修饰常量名。下面是一个例子:1 public interface PhysicalConstants {2 static final原创 2020-12-29 22:31:46 · 84 阅读 · 0 评论 -
Effective Java 接口优于抽象类
Java有两种机制来定义允许多个实现的类型:接口和抽象类。 由于在Java 8 [JLS 9.4.3]中引入了接口的默认方法(default methods ),因此这两种机制都允许为某些实例方法提供实现。 一个主要的区别是要实现由抽象类定义的类型,类必须是抽象类的子类。 因为Java只允许单一继承,所以对抽象类的这种限制严格限制了它们作为类型定义的使用。 任何定义所有必需方法并服从通用约定的类都可以实现一个接口,而不管类在类层次结构中的位置。现有的类可以很容易地进行改进来实现一个新的接口。 你只需添加原创 2020-12-28 22:25:25 · 131 阅读 · 0 评论 -
Effective Java 要么为继承设计,并提供文档说明,要么就禁止继承
首先,该类的文档必须精确地描述覆盖每个方法所带来的影响。换句话说,该类必须有文档说明他可覆盖(overridable)的方法的自用型(self-use)。对于每个共有的或受保护的方法或构造器,他的文档必须指明该方法或者构造器调用了哪些可覆盖的方法,是以什么顺序调用的,每个调用的结果又是如何影响后续的处理过程的。更一般的,类必须在文档中说明,在哪些情况下会调用可覆盖的方法。(例如:后台的线程或者静态的初始化可能会调用这个方法)按惯例,如果方法调用了可覆盖的方法,在他的文档注释的末尾应该包含关于这些调用的描原创 2020-12-27 19:52:26 · 92 阅读 · 0 评论 -
Effective Java 复合优先于继承
继承是实现代码重用的有力手段,但是使用不当会导致软件变得脆弱。在包的内部使用继承是非常安全的,子类和超类的实现都处在同一个程序员的控制之下。对于专门为了继承而设计、并且具有很好的文档说明的类来说,使用继承也是非常安全的。然而们对于进行跨越包边界的继承,则要非常小心。“继承”在这里特指一个类扩展另一个类。public class InstrumentedHashSet<E> extends HashSet<E> { private int addCount =.原创 2020-12-26 17:38:45 · 119 阅读 · 0 评论 -
Effective Java 使可变性最小化
不可变类是实例不能被修改的类。每个实例中包含的所有信息都必须在创建该实例的时候就提供,并在对象的整个生命周期内固定不变。Java平台包含的不可变类:String、基本类型的包装类、BigInteger、BigDecimal。不可变类比可变类更容易设计、实现和使用。为了使类成为不可变,要遵循五条规则:1.不要提供任何会修改对象状态的方法。2.保证类不会被扩展,为了防止恶意子类假装对象状态被改变,从而破坏不可变。3.使所有的域都是final的。4.使所有的域都成为私有的,防止客户端获得.原创 2020-12-26 13:33:56 · 105 阅读 · 0 评论 -
Effective Java 在公有类中使用访问 方法而非公有域
Class Point { public double x; public double y;}如上面Point类的数据域是可以直接被访问的,这样的类没有提供封装。如果不改变API,就无法改变它的数据表示法(比如,使用一个比double更高精度的类来表示x和y),也无法强加任何约束条件(比如以后我们可能会希望x和y不会超过某个值)。Class Point { private double x; private double y; public..原创 2020-12-24 20:27:36 · 86 阅读 · 4 评论 -
Effective Java使类和成员的可访问性最小化
要区分精心设计的组件和设计不好的组件的最重要的因素在于,这个组件对于其他组件而言,是否隐藏了其内部数据和其他市县细节。设计良好的组件会隐藏其所有实现细节,把它的API与它的实现完全分离。组件之间只能通过它们的API进行通信,并且不知道彼此之间内部的工作细节。这种被称为信息隐藏(information hiding )或封装(encapsulation)的概念是软件设计的基本原则[Parnas72]。 信息隐藏之所以非常重要是有许多原因的,其中大部分原因在于它将构成系统的组件解耦,允许它们单独开发、测试原创 2020-12-24 20:12:40 · 106 阅读 · 1 评论 -
考虑实现Comparable接口
考虑实现Comparable接口与本章中讨论的其他方法不同,compareTo方法并没有在Object 类中声明。相反,它是Comparable 接口中唯一的方法。compareTo方法不但允许进行简单的等同性比较,而且允许执行顺序比较,除此之外,它与Object的equals方法具有相似的特征,它还是个泛型(generic)。类实现了 Comparable接口,就表明它的实例具有内在的排序关系 (natural ordering)。为实现Comparable接口的对象数组进行排序就这么简单:Array原创 2020-12-20 19:21:50 · 175 阅读 · 0 评论 -
Effective Java 谨慎的覆盖clone()方法
一个类要想实现克隆,需要实现Cloneable接口,表明这个类的对象具有克隆的功能。Cloneable接口是一个mixin接口,它里面并没有任何的抽象方法,类似的接口有Serializable接口,表明该类的对象可以序列化。首先应该明确通过一个对象克隆出另一个对象的概念:通过一个对象克隆出另一个对象,简称对象1和对象2,这两个对象就成为两个独立的对象,那么对对象1做任何的修改,对象2应该不受影响;对对象2做任何的修改的,对象1就不应该受影响。这样就要求对象1与对象2的实例域各自是独立的。那么我们知道原创 2020-12-20 18:07:22 · 129 阅读 · 0 评论 -
Effective Java始终要覆盖toString()方法
Object类提供的toString()方法如下:public String toString(){return getClass().getName() + “@” + Integer.toHexString(hashCode());}如果我们直接打印一个对象,就会调用这个对象的toString()方法,如果我们没有为该类覆盖toString()方法,我们可以看出toString()方法,返回的是 “类名@散列值的十六进制”。toString()方法的通用约定是:返回当前对象“简洁,但信息丰原创 2020-12-19 20:48:54 · 153 阅读 · 3 评论 -
Effective Java 覆盖equals时总要覆盖hashCode
一. Object.hashCode通用约定1. 在应用程序执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数. 在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致 2. 如果两个对象根据equals(Object)方法比较是想等的,那么调用两个对象总任意一个对象的hashCode方法都必须产生同样的整数结果 3. 如果两个对象根据equals(Object)方法比较是不想等的,那么原创 2020-12-19 20:33:38 · 98 阅读 · 1 评论 -
Effective java 覆盖equals时请遵守通用约定
该篇博客主要阐述1、不需要覆盖equals的情景2、需要覆盖equals的情景3、对5条通用约定的理解4、实现高质量equals的诀窍5、注意点一、不需要覆盖equals的情景1、类的每个实例本质上都是唯一的对于代表活动实体而不是值(value)的类来说确实如此,比如Thread2、不关心类是否提供了“逻辑相等”的测试功能书本上的例子是java.util.Random覆盖equals,以检查两个Random实例是否产生相同的随机数序列,但是设计者并不认为客户需要或者期望这样的功能。在这种原创 2020-12-19 18:10:48 · 101 阅读 · 1 评论 -
Effective Java 避免使用终结方法和清空方法
终结方法是不可预测的,通常很危险,一般情况下是不必要的(Finalizers are unpredictable, often dangerous, and generally unnecessary.)。使用 终结方法会导致行为不稳定,降低性能,以及可移植性问题。当然,终结方法也有可用之处,我们将在本项的最后再做介绍;但是,作为一项规则,我们应该避免使用它们。在Java 9 中,终结方法已经过时了,但是在Java库中还在使用。Java 9中替代终结方法的方式是清理方法。清理方法比终结方法危险性更低,但仍然原创 2020-12-15 21:49:45 · 223 阅读 · 0 评论 -
Effective Java 清除过期对象的引用
当你从手工管理内存的语言(比如C或者C++)转换到具有垃圾回收功能的语言的时候,程序猿的工作就会变得更加容易,因为当你用完了对象之后,他们就会被自动回收。当你第一次经历对象回收功能的时候,会觉得这简直有点不可思议。这很容易给你留下这样的印象,认为自己不再需要考虑内存管理的事情了,其实不然。 考虑下面这个简单的栈实现的例子:// Can you spot the "memory leak"?public class Stack { private Object[] elements;原创 2020-12-14 22:13:55 · 213 阅读 · 2 评论 -
Effective Java 避免创建不必要的对象
《Effective Java》第二章创建和销毁对象第5条提到,在开发过程中,需要避免创建不必要的对象,最好能重用对象而非在每次需要的时候就创建一个相同功能的新对象。如果对象是不可变的,它就始终可以被重用,而不用创建新的实例,从而降低内存占用和垃圾回收的成本。例如,创建字符串// Don't do this!String s = new String("stringette");// 优化版String s = "stringette"; 第二行代码每次被执行的时候都创建一个...转载 2020-12-14 21:13:23 · 111 阅读 · 0 评论 -
Effective Java——通过私有构造器强化不可实例化的能力
有时候你会想要编写一个只包含一组静态方法和静态字段的类。这种类名声很不好,因为有些人为了避免使用面向对象的思维方式而滥用这样的类(some people abuse them to avoid thinking in terms of objects),但是他们确实有它们特有的用处。我们可以使用这种类,以java.lang.Math或者java.util.Arrays的方式对原始值或数组的相关方法组织起来。它们还可以用于以java.util.Collections的方式,把实现特定接口的对象上的静态方法(.转载 2020-12-11 22:23:44 · 83 阅读 · 1 评论 -
Effective Java——用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类 [Gamma95]。Singleton通常代表无状态的对象,例如函数(第24项)或者本质上唯一的系统组件。使类称为Singleton会使它的客户端测试变得十分困难,因为除非它实现了作为其类型的接口,否则不可能将模拟实现替换为单例。 实现单例的方法有两种。 两者都基于保持构造函数私有并导出公共静态成员以提供对唯一实例的访问。 在一种方法中,该成员是final字段:// Singleton with public final fieldpublic cla转载 2020-12-11 22:13:26 · 156 阅读 · 0 评论