您现在的位置是:首页 > 正文

《Effective Java》阅读笔记 13使类和成员的可访问性最小化

2024-01-31 00:15:51阅读 0

1.信息隐藏

区分一个组件设计得好不好,唯一重要的因素在于,它对于外部的其他组件而言,是否隐藏了其内部数据和其他实现细节。设计良好的组件会隐藏所有的实现细节,把API与实现清晰地隔离开来。然后模块之间只通过它们的 API 进行通信,一个模块不需要知道其他模块的内部工作情况。这种概念被称为 信息隐藏 或者 封装,是软件设计地基本原则之一。

信息隐藏之所以非常重要有许多原因,其中大多是因为:它可以有效地解除组成系统地各组件之间地耦合关系,即解耦,使得这些组件可以独立地开发、测试、优化、使用、理解和修改

2.为什么要使类和成员的可访问性最小化?

虽然信息隐藏本身无论是对内还是对外都不会带来更好地性能,但是可以有效地调节性能:一旦完成一个系统,并通过剖析确定了那些组件影响了系统地性能(详见第67条).

  • 那些组件就可以被进一步优化,而不会影响到其他组件地正确性

  • 信息隐藏提高了软件地可重用性。因为组件之间并不紧密相连,除了开发这写模块所使用地环境之外,它们在其他地环境中往往也很有用。

  • 最后,信息隐藏也降低了构建大型系统地风险。因为即使整个系统不可用,这些独立地组件仍然有可能是可用的。

因此,可以有效的解除系统中各个模块的耦合度、实现每个模块的独立开发、使得系统更加的可维护,更加的健壮。

3.如何最小化类和接口的可访问性?

(1)能将类和接口做成包级私有就一定要做成包级私有的。
(2)如果一个类或者接口,只被另外的一个类应用,那么最好将这个类或者接口做成其内部的私有类或者接口。

4.对于成员(域、方法、嵌套类和嵌套接口)访问级别

对于成员(域、方法、嵌套类和嵌套接口),有四种可能的访问级别

  • 1.私有的(private):只有在声明该成员的顶层类内部才可以访问这个成员。
  • 2.包级私有(package-private):声明该成员的包内部的任何都可以访问这个成员。从技术上将,他被称为“缺省”(default)访问级别,如果没有为成员指定访问修饰符,就采用这个访问级别(当然,接口成员除外,它们默认的访问级别是公有的)。
  • 3.受保护的(protected):声明该成员的类的子类可以访问这个成员(但是有一些限制,并且声明该成员的包内部的任何类也可以访问这个成员)。
  • 4.共有的(public):在任何地方都可以访问该成员。
    在这里插入图片描述

5. 如何最小化一个类中成员的可访问性?

  • (1)首先设计出该类需要暴露出来的api,然后将剩下的成员设计成private类型。然后再其他类需要访问某些private类型的成员时,在删掉private,使其变成包级私有。如果你发现你需要经常这样做,那么就请你重新设计一下这个类的api
  • (2)对于protected类型的成员,作用域是整个系统,所以,能用包访问类型的成员的话就尽量不要使用保护行的成员
  • (3)不能为了测试而将包中的类或者成员变为public类型的,最多只能设置成包级私有类型
  • (4)实例域绝对不能是public类型的。静态域也一样
  • (5)如果一个包级私有的顶层类只是在某一个类的内部被用到,就应该考虑使它成为唯一使用它的那个类的私有嵌套类。.
  • (6)接口中的方法必须是共有的,导致所有实现该接口的类方法都隐含着共有访问级别。公有类永远都不应该暴露可变的域。对于不可变的域可以提供get访问方法,对于可变的提供get&set方法。.
  • (7)假设常量构成了类提供的整个抽象的一部分,可以通过公有的静态final域来暴露这些常量。按惯例,这种域的名称由大写字母组成,单词之间用下划线隔开(详见第68条)。很重要的一点是,这些域要么包含基本类型的值,要么包含指向不可变对象的引用(详见第17条)。.

6.注意点

  • 包含共有可变域的类不是线程安全的
  • 静态final域要不包含基本类型的值,要不包含指向不可变的引用,不然会导致灾难。
  • 长度为0的数组都是可变的,声明为final也没用。可以使用两种方法,一是私有数组域,公有unmodifiableList;二是私有数组域,公有clone方法
// Potential security hole!
public static final Thing[] VALUES = { ... };
使共有数组变成私有的,并增加一个公有的不可变列表:
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
返回私有数组的一个拷贝
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
    return PRIVATE_VALUES.clone();
}
  • 方法覆盖超类的一个方法,访问的级别不允许低于超类中的访问级别。这样可以确保任何可使用超类的实例的地方也都可以使用子类的实例(详见第10条)。

7.参考文献

https://www.taodudu.cc/news/show-2297813.html
在这里插入图片描述

本公众号分享自己从程序员小白到经历春招秋招斩获10几个offer的面试笔试经验,其中包括【Java】、【操作系统】、【计算机网络】、【设计模式】、【数据结构与算法】、【大厂面经】、【数据库】期待你加入!!!

1.计算机网络----三次握手四次挥手
2.梦想成真-----项目自我介绍
3.你们要的设计模式来了
4.一字一句教你面试“个人简介”
5.接近30场面试分享

网站文章

  • C语言(CED)对于一个2行N列的走道。现在用1*2,2*2的砖去铺满。问有多少种不同的方式(递归求解)

    C语言(CED)对于一个2行N列的走道。现在用1*2,2*2的砖去铺满。问有多少种不同的方式(递归求解)

    又涉及到递归问题,这道题的大致内容是这样的: (请用递推方式求解)对于一个2行N列的走道。现在用1*2,2*2的砖去铺满。问有多少种不同的方式。下图是一个2行17列的走道的某种铺法。 提示:观察前n个结果,可以得到递推式子;如果N很大,需要高精度计算。 其实这道题,与之前的方格涂色问题很像,说它像不仅因为在思考方式上很像,在最后的代码上也很想像,听我一一道来。 题目提示,先观...

    2024-01-31 00:15:42
  • JAVA WEB:西蒙购物网 实现页面 资源及代码

    JAVA WEB:西蒙购物网 实现页面 资源及代码

    一、准备资源1、图片在web目录里创建images目录,存放项目所需图片文件:2、css样式文件在web里创建css目录,在里面创建main.css文件:/* 样式 */body { margin: 0px; text-align: center; background: url("../images/frontBack.jpg") no-repeat;...

    2024-01-31 00:15:33
  • Mysql  ----------  安装

    Mysql ---------- 安装

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。优点:关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。可以在官网下载地址: https://dev.mysql.com/downloads/安装:同意选择完整安装...

    2024-01-31 00:15:04
  • Django ORM:数据库操作的Python化艺术

    Django的对象关系映射器(ORM)是其核心功能之一,允许开发者使用Python代码来定义、操作和查询数据库。

    2024-01-31 00:14:57
  • kubernetes env资源引用

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 @关于kubernetes env资源注入 前言 关于kubernetes env引用变量方式有configMap,DownwardA...

    2024-01-31 00:14:51
  • 蓝桥杯开发板CT107D使用 IAP15F2K61S2芯片时晶振频率的选择

    蓝桥杯开发板CT107D使用 IAP15F2K61S2芯片时晶振频率的选择

    蓝桥杯开发板CT107D上使用的晶振为12MHZ,在进行烧录和软件延时需要对晶振频率进行选择。而烧录软件一般默认为11.0592MHZ. 只需要将两个频率保持一致即可(一般在12和11.0592中选择一个),直接上图 选择 12MHZ 11.0592MHZ ...

    2024-01-31 00:14:45
  • Workerman ThinkPHP5 宝塔 安装Event拓展

    Workerman ThinkPHP5 宝塔 安装Event拓展

    Workerman 结合 TP5在宝塔环境下安装Event拓展操作系统是CentOS7先用workerman官方给的检查环境的脚本进行检查curl -Ss http://www.workerman.n...

    2024-01-31 00:14:18
  • selenium自动化-下拉列表

    selenium自动化-下拉列表

    selenium操作下拉列表select/option标签举个例子ul/li标签验证js是否能选中未显示的值结论python代码实现 selenium自动化获取对象时,肯定会涉及到下拉列表,项目中遇到...

    2024-01-31 00:14:10
  • Vue基础升级

    Vue基础升级

    生命周期函数面试题 1.什么是 vue 生命周期;2.vue生命周期的作用是什么 Vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组...

    2024-01-31 00:14:03
  • Excel之单元格数字格式

    Excel之单元格数字格式

    文本与常规格式的正常转换 单元格格式一般分两种文本与常规 分列工具大部分是用于修改单元格的格式 文本数据不能正常的运算,像身份证号电话等等这些一般都是文本 常规的数据可以正常运算 文本如何转换成常规格...

    2024-01-31 00:13:33