Java如何创建不可变类
来源:才华咖 本文已影响3.24W人
来源:才华咖 本文已影响3.24W人
大家知道Java如何创建不可变类吗?下面小编为大家解答一下,希望能帮到大家!
class:java中class确切的表示为一个类
object:java中object确切的表示为一个对象,也称为类的实例
其实,如果一个类被设计成不可变的类,那么这个类的实例化对象也是不可变的。
不可变类:当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。
那么,什么是不可变对象?
一旦一个类的实例化对象被创建并初始化,那么它就不可以被改变。我们可以调用访问器方法(getter),复制对象,或者传递对象,但是不允许任何方法改变这个对象的状态。包装类(ger或Float)和String类是不可变类的代表。
访问器方法(accessor method):对成员变量做出访问的方法,er()方法。
修改器方法(mutator method):对成员变量做出修改的方法,er()方法。
定义一个不可变类
如果我们要自己创建一个不可变类,需要遵守下面的规则:
将成员变量(field:在一些书中也翻译为域)声明成final并在构造器中初始化。
对于基本类型的成员变量,用final修饰,一旦它被初始化,就不能被改变了。而对于引用类型的成员变量,不能够改变它的引用。
成员变量如果被声明称final,那么构建对象时,必须要初始化这样的域
引用类型是可变的,我们需要采取一些措施来保证它的不可变性。
为什么?如果我们只是声明了一个final的可变引用类型,那么这个引用可以去引用外部的类,或者被其他外部类引用。在这种情况下,我们要做到:
1.这些方法不会改变这些可变对象中的内容
2.不要将这些引用分享到外部供其他类使用,例如,如果对成员变量的引用是可以被其他类改变的,那么这些外部类就可以改变这个类中的内容。
3.如果必须要返回一个引用,那么就返回一个对象的`深度拷贝,这样尽管返回的对象内容改变了,但也保存着原始的内容。
只提供访问器方法(i.e. getter方法)不提供修改器方法(er方法)
如果一定要改变这个对象的内容,那就创建一个新的不可变对象内容做相应的修改,返回修改后的对象的引用声明类是final的。如果一个类可以被继承,那么它子类就可以重载它的方法,并且修改成员变量
Java API中不可变类的例子
让我们来回顾一下String类,用它来理解上述的几个方面在String类实现中的体现:
所有在Stirng类中成员变量都被声明成private,这些成员变量都在构造器中在构建对象时被初始化。
trim concat substring 都可以改变String的对象,为了保证String的不可变性,这些方法都返回的是一个改变相应内容后新的对象。
string类被声明称final,所以任何类都不能继承,重载它的方法。
自己实现一个不可变类
接下来我们自己实现一个不可变类ImmutableCircle。
//
// Point is a mutable class
class Point {
private int xPos, yPos;
public Point(int x, int y) {
xPos = x;
yPos = y;
}
public String toString() {
return "x = " + xPos + ", y = " + yPos;
}
int getX() { return xPos; }
int getY() { return yPos; }
}
// ImmutableCircle is an immutable class – the state of its objects
// cannot be modified once the object is created
public final class ImmutableCircle {
private final Point center;
private final int radius;
public ImmutableCircle(int x, int y, int r) {
center = new Point(x, y);
radius = r;
}
public String toString() {
return "center: " + center + " and radius = " + radius;
}
public int getRadius() {
return radius;
}
public Point getCenter() {
// return a copy of the object to avoid
// the value of center changed from code outside the class
return new Point((), ());
}
public static void main(String []s) {
tln(new ImmutableCircle(10, 10, 20));
}
// other members are elided ...
}
上面的程序运行之后,打印:
center: x = 10, y = 10 and radius = 20
上面的程序体现了不可变类的以下几点:
· 这个类被声明成final,不可以被继承,也不可以重载它的方法
· 这个类的成员变量都是final并且是私有的
· 因为成员变量center是一个引用类型,是可变的,所以在他的getter方法中,返回的是对point对象的拷贝
设计一个不可变的类最关键的一点:
要注意引用类型的成员变量,如果成员变量的类型是可变的引用类型,就必须要采取必要的措施来保护这个成员变量不会被修改
不可变类不足的地方
不可变对象同样也有不足的地方。为了保证不可变性,不可变类中的方法会创建出一定量的对象的拷贝。例如,在上面的代码中,每次调用getcenter方法都会新建并返回一个point对象的拷贝。而假如我们只需要调用一次,返回一个point对象,就没必要费尽心神的去设计一个不可变类,仅仅只需要一个可变的immutablecircle类就可以了。
String类在很多应用场景中都会用到,如果我们调用String类中trim,concat,或者是在循环中调用substring方法,都会创建一个新的临时String对象。同时,java也提供了Stringbuffer和Stringbuilder的可变类。他们同String一样,但是却可以改变这个对象的内容。所以,我们可以根据不同的场景使用String类或者Stringbuffer/Stringbuilder类。
Java入门教程:如何使用一个Java
如何检查JavaScript变量的类型
如何创建并运行Java线程
java Runnable接口如何创建线程
Java4安卓开发教程之java的变量
Java认证考试知识点:Java时间类的函数
Java零基础如何学好Java语言
经典Java面试题之Java中Char类型的运算
Java import以及Java类的搜索路径
java与JavaScript语言有何不同
Java类库及其组织结构(Java API)
JavaScript与java语言有何不同
如何学好Java 学习Java的步骤介绍
java环境变量如何设置
Java 2.1 java基本类型的转换和运算符
Win7系统如何配置java环境变量
Java数据类型以及变量的定义
在Mac上如何卸载Java
Java类如何获取Spring的bean
如何在Mac上卸载Java
Java与Java web有什么不同
Java的变量类型有哪些
Java如何读取Jar中的资源
如何搭建Java程序开发环境
可望而不可即如何造句
如何在Dreamweaver中为网页插入Java程序
Java中的String为什么是不可变的
如何创建简历
Java 变量类型介绍
java如何读取CSV
从Java的jar文件中如何读取数据的方法
Java语言的作用域有哪些及如何分类
如何区分Java中抽象类和接口
计算机二级JAVA考试构建JAVA程序2017
Java 变量类型
面试时如何以不变应万变
JAVA认证开源技术:关于Java的对象equals方法
如何在Mac上安装Java
java语言如何建立一个画布
Java中对象类型如何进行转换