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传递对象引用的时候只复制了对象引用的地址。

类设计技巧

  1. 一定要保证数据私有,即封装性;
  2. 一定要对数据初始化,最好不要依赖系统的默认值,自己给定一个初始值;
  3. 不要在类中使用过多的基本类型,可以把相关的几个变量合成一个class,转为引用class,另外,能用包装类就不用基本类型;
  4. 不是所有的成员变量都应该提供对外访问方法,比如创建日期不可以修改;
  5. 将职责过多的类进行分解;
  6. 类名和方法名要能够体现他们的职责;
  7. 优先使用不可变的类。

原文地址:https://www.cnblogs.com/woshimrf/p/java-class.html

时间: 2024-08-30 11:51:50

Java复习2-对象与类的相关文章

java基础知识-对象和类

前言: 因为要准备Java面试,所有将java基础知识点重新复习一遍,主要笔记来源于菜鸟教程和java核心技术的书籍中,也有一些博客上的资料(这些只供我个人学习使用) Java 对象和类 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有:摇尾巴.叫.吃等. 类:类是一个模板,它描述一类对象的行为和状态. 下图中男孩女孩为类,而具体的每个人为该类的对象: 1.Java中的对象 现在让我们深入了解什么是对象.看看周围真实的世界,会发现身边有很多对象

JavaSE复习_2 对象与类

△java中的制表符.'\t'制表符."\t"也可以. △方法内不能再定义一个方法,互相平级. △数组中boolean类型的变量默认为false;char默认为'\u0000'(\u是unicode 的一种标识,标识16进制) △int [ ]a=new int[4]{1,2,3,4};非法 int [ ]a=new int[]{1,2,3,4};合法 int [ ]a=new int[]{1,2,3,4};可以在不同行,先声明,后赋值如: int [ ]a; a=new int[ ]

java之常见对象-Object类

1.API概述 API(Application Programming Interface),应用程序编程接口. 编写一个机器人程序去控制机器人踢足球,程序就需要向机器人发出向前跑.向后跑.射门.抢球等各种命令,没有编过程序的人很难想象这样的程序如何编写.但是对于有经验的开发人员来说,知道机器人厂商一定会提供一些用于控制机器人的java类,这些类中定义好了操作机器人各种动作的方法.其实,这些java类就是机器人厂商提供给应用程序编程的接口,大家把这些类就称为应用程序编程接口. 2.java AP

java学习笔记(Core Java)4 对象与类

第四章 对象与类oop三个特征:对象的行为.状态.标识类之间关系:依赖,聚合,继承依赖:一个类的方法操纵另一个类的对象.(尽量减少这种耦合情况)聚合(has-a)一个类作为另一个类的变量而存在继承(is-a) 如果只声明一个类变量,而没有在堆空间中开辟没存,那么这个变量就不能调用类中的方法因为这个变量没有引用对象 !!一个对象的变量并没有实际包含一个对象,而仅仅引用了一个对象 Data data;等同于:Data *data; //它只代表一个指针,而不拥有对象数据 get/set 访问器 一个

Java复习笔记1--抽象类和接口

这一系列是今年7月份至8月份为实习面试所复习的Java功课~ 抽象类和接口 是Java 对抽象概念进行定义的2种机制. 抽象类 一个类没有足够的信息来描述一个具体的对象,需要其他具体的类才支撑它. 抽象类体现了数据抽象的四小,是实现多态的一种机制. 它定义了一组抽象的方法,至于这组抽象方法的具体表现形式有派生类来实现.同时抽象类提供了继承的概念,它的出发点就是为了继承,否则它没有存在的任何意义.所以说定义的抽象类一定是用来继承的,同时在一个以抽象类为节点的继承关系等级链中,叶子节点一定是具体的实

Java第二章----对象和类

从第一章到第二章整整隔了一个月的时间,这速度也是慢的无语了.因为这个月负责开发公司一个SaaS类型APP,忙的昏天暗地终于上线了,这才有时间写个博客.本章还是以概念为主,有点枯燥重在理解. 第一节:对象 名词解释 OOA-Object Oriented Analysis-面向对象分析 OOD-Object Oriented Design-面向对象设计 OOP-Object Oriented Programming-面向对象程序设计 面向对象基本特性 万物皆可为对象:任何一件事物都可以表示为程序中

浅谈java中的对象、类、与方法的重载

对象: 一切皆为对象. 对象包括两部分内容:属性(名词形容词),行为(动词). 对象和对象之间是有关系的: 派生,关联,依赖. 类: 对同一类别的众多对象的一种抽象. 类,还是用来生成对象的一种模板,对象是类的一种具体化的表现. 面向对象的三大特性:封装,继承,多态. ? 1 2 3 4 class 类名{ 访问修饰符 成员变量的定义; 访问修饰符 成员函数(方法)的定义; } 访问修改符:默认不写,private,public. private,私有.只能被当前class 类名{}中的代码访问

JAVA学习记录①——对象、类、属性、方法、构造方法的总结

对象——现实存在的手机(三星.苹果) 类——虚拟的手机(包含属性:5.0寸屏幕,2.1GHZCPU等,方法:能打电话,玩游戏) 属性:手机的配置(5.0寸屏幕,2.1GHZCPU) 方法:手机能做什么的(能打电话,玩游戏) 构造方法:用来给手机赋初值 具体展示在下面: /* * 文件一 * 这是类文件,用来保存手机的性质以及如何赋初值 * */ //这是类 public class Telphone { //这是属性,表示手机应该拥有什么 double screen; double cpu; /

Java 复习 —— 集合数组帮助类

1.集合帮助类 基本就这些了,关键是要了解 Collections 是集合的帮助类,不是数组的帮助类: 1)生成只读的集合实例对象 Collections.singletonList--用来生成只读 的单一元素的List Collections.singletonMap--用来生成只读 的单Key和Value组成的Map Collections.singleton--用来生成只读 的单一元素的Set Collections.unmodifiableList--用来生成只读 的List Colle