Java复习2-对象与类
回顾基础知识过程中遇到的感觉需要记录一下的知识点。
封装
我们设计的class应当尽可能的高内聚,体现为封装的程度。一个class的属性应该只能自己修改,其他class都只是与本class沟通,而不应该有能力修改。比较常见的一个问题是Date属性。
业务开发中经常需要设计class的日期属性,比如birthday, createDate等。
public class User {
private String name;
private Date birth;
public Date getBirth() {
return this.birth;
}
}
我经常设计一个entity,填入字段,然后就直接getter, setter出去,尤其使用lombok后,更是连生成都改自动了。按照封装的要求,这样的做法是不合适的。因为其他class可以获取Date对象,Date对象是可变的。那么,就有可能会产生日期被修改的可能。
如果项目有引入Findbugs的扫描,这个class肯定会被扫描出来的,不应该返回一个可变对象。那么,怎么做才可以避免这个问题?我们确实需要暴露Date啊。
答案是暴露一个不可变的对象。Java8推出了新的日期API,其中LocalDate就是不可变的。用LocalDate替换Date即可。LocalDate就像String一样,没有提供任何可以改变内部属性的方法,所有的修改之类的方法都将会创建一个新的对象。这样,修改操作将不会影响原来的class。
Date对象可以解决,但很多是自己定义的对象,这个怎么办?比如,User有个属性是Role。
public class User {
private String name;
private LocalDate birth;
private Role role;
public Role getRole() {
return this.role;
}
}
和Date类似,当调用getRole之后,外界如果可以修改role的属性,比如把role改成admin,那么本对象就拥有了admin权限了。这是我们不愿看到的。可以模仿LocalDate,把Role的所有修改内部属性的方法关闭。这样,外部无法修改Role,就不会影响到User了。然而,我们web中需要把对象渲染成json发送出去,jackson会根据getter setter去做序列化和反序列化操作。这个setter还不能关闭。
那就只能处理User自己了。user唯一发生风险的地方在于getRole后,把自己内部属性暴露出去了。我们可以getRole的时候给一个新的出去,让其他class随便改都不会影响自己。
public class User {
private String name;
private LocalDate birth;
private Role role;
public Role getRole() {
return (Role) this.role.clone();
}
}
现实是,我们很少关注这样的做法,都是直接返回。而且,也很少遇到错误。这时候可以 忽略findbugs的异常。但,最好的,还是推荐做这样的修改。
方法传参的按值调用
初学Java的时候最容易搞不懂的地方就是传递参数到底是怎么传递的。
在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。按值调用(call by value)表示方法接收的是调用者提供的值。而按引用调用(call be reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。按...调用(call by)是一个标准的计算机科学术语,它用来描述各种程序设计语言(不只Java)中方法参数的传递方式。
Java程序设计语言总是按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
int a = 10;
addOne(a)
不管addOne方法具体实现,a最终依旧还是10. 因为当a传递给addOne方法的时候,拷贝了一份a的值给参数,方法中运行过程中都是一份拷贝,不会影响原来的变量。
方法参数共有两种:
- 基本数据类型(数字、布尔值)
- 对象引用
上述demo显示一个方法不可能修改一个基本数据类型的参数。那么对象引用呢?
StringBuilder sb = new StringBuilder();
appendOne(sb);
appendOne执行过程中会对sb产生影响吗?
这就要看具体方法内容了。比如
public void appendOne(StringBuilder sb) {
sb.append("1");
}
那么,我们最终执行完结果肯定sb内容添加了1。而换一个方式,
public void appendOne2(StringBuilder s){
s = new StringBuilder();
s.append("a");
}
这样,方法外面的sb的内容会变成什么?
这个,首先要记住的是Java方法传参都只是传递拷贝。然后,明白传递拷贝的意义

因为s指向的地址和sb相同,故,当s.append的时候,sb的内容也会改变。这也上开头讲述的封装不应返回一个可变变量的原因。任何拿到这个可变变量地址的方法都可以直接修改变量里的属性。那方法2有什么不同?

方法2中,把参数s指向了新地址,那么接下来的任何修改,都将不会影响旧地址。则方法外的sb对应的地址空间也就不会发生变化。这个可以理解为Java传递对象引用的时候只复制了对象引用的地址。
类设计技巧
- 一定要保证数据私有,即封装性;
- 一定要对数据初始化,最好不要依赖系统的默认值,自己给定一个初始值;
- 不要在类中使用过多的基本类型,可以把相关的几个变量合成一个class,转为引用class,另外,能用包装类就不用基本类型;
- 不是所有的成员变量都应该提供对外访问方法,比如创建日期不可以修改;
- 将职责过多的类进行分解;
- 类名和方法名要能够体现他们的职责;
- 优先使用不可变的类。
Java复习2-对象与类的更多相关文章
- 关于Java中的对象、类、抽象类、接口、继承之间的联系
关于Java中的对象.类.抽象类.接口.继承之间的联系: 导读: 寒假学习JavaSE基础,其中的概念属实比较多,关联性也比较大,再次将相关的知识点复习一些,并理顺其中的关系. 正文: 举个例子:如果 ...
- JavaSE复习_2 对象与类
△java中的制表符.'\t'制表符."\t"也可以. △方法内不能再定义一个方法,互相平级. △数组中boolean类型的变量默认为false;char默认为'\u0000'(\ ...
- java基础(二) -对象和类
Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为.例如,一条狗是一 ...
- java中的对象、类、包、模块、组件、容器、框架、架构的概念入门
在Java中有那么一些概念:对象.类.包.模块.组件.容器.框架.这些概念都有一个共同的特点,就是[容纳]. 对象(Object) 在Java的世界里,对象是通过属性和方法来分别对应事务所具有的静态属 ...
- Java 学习:对象和类
对象和类 从认识的角度考虑是先有对象后有类.对象,是具体的事物.类,是抽象的,是对对象的抽象. 从代码运行角度考虑是先有类后又对象.类是对象的模板. 对象:对象是类的一个实例,有状态和行为. 类:类是 ...
- Java中的对象、类、抽象类、接口的理解
1.对象 对象是个具体的东西,有着明确的属性特征和行为特征. 例如:你手上牵着的女朋友或男朋友就是个具体的对象. 如图中的苏格兰折耳猫,特征是耳朵向下呈折叠状,有着具体的颜色(你看到的颜色),并且和其 ...
- Java第二章----对象和类
从第一章到第二章整整隔了一个月的时间,这速度也是慢的无语了.因为这个月负责开发公司一个SaaS类型APP,忙的昏天暗地终于上线了,这才有时间写个博客.本章还是以概念为主,有点枯燥重在理解. 第一节:对 ...
- java中的对象和类
1.类:类是一个模板,它描述一类对象的行为和状态. 一个类可以包含以下类型变量: 局部变量:在方法.构造方法或者语句块中定义的变量被称为局部变量.变量声明和初始化都是在方法中,方法结束后,变量就会自动 ...
- java中的对象,类。与 方法的重载。
对象: 一切皆为对象.对象包括两部分内容:属性(名词形容词),行为(动词).对象和对象之间是有关系的: 派生,关联,依赖. 类: 对同一类别的众多对象的一种抽象.类,还是用来生成对象的一种模板,对象是 ...
随机推荐
- 有强大的cURL,忘掉httpclient的吧!
这段时间想做一个网页采集的程序,由于一网站采用了防采集的办法,我的httpclient总是在登录后无法获取到我想要过去的链接.在无数次的跟踪过后发现原来人家给返回的是javascript拼成的页面,而 ...
- 硬盘img镜像备份工具
linux下使用dd,Windows下使用WinImage,不过dd使用的比较多.
- .net core中的System.Buffers名字空间
最近研究了一下.net core 2.1的基础类库,发现它引入了一个System.Buffers名字空间,里面提供了一系列比较实用的对象,便简单的管中窥豹浏览一下. ArrayPool<T> ...
- Eclipse 正则表达式 查找与替换
CTRL + space in the textboxes gives you all kinds of suggestions for regular expression writing. 查找 ...
- rcp(插件开发)点击按钮出现 The chosen operation is not enabled 解决办法
别的项目组,遇到以下错误信息: 首先看一下log日志里的异常信息,估计就知道是什么问题了. 项目组遇到的这个错误是source 指向错误 找不到相关的class.
- C#访问远程主机资源的方法,多种方式
最近要实现访问远程主机的共享目录中的一个文件.遇到了权限问题.google了一下,找到了几种解决方法,记录如下: 一.调用Net use命令 // 使用方法: //if (Connect ...
- 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容
在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...
- 关闭Delphi的RTTI
{$IF CompilerVersion >= 21.0}{$WEAKLINKRTTI ON}{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS( ...
- Windows/Linux下引用jar包,并用javac/java编译运行
Windows/Linux下引用jar包,并用javac/java编译运行,有需要的朋友可以参考下. 1> Windows 假设要引用的jar放在D:/test目录下,名字为t1.jar, ja ...
- MySql错误处理(二) - Condition & Handle
20.2.10. 条件和处理程序 20.2.10.1. DECLARE条件 20.2.10.2. DECLARE处理程序 特定条件需要特定处理.这些条件可以联系到错误,以及子程序中的一般流程控制. 2 ...