`

安全的类构造器[摘自effective java]

 
阅读更多

原始的类的设计如下

import java.util.Date;

public final class SafeMain {
	
	private final Date start;
	
	private final Date end;
	
	private final int name;
	
	public SafeMain(Date start,Date end,int name){
		if (start.compareTo(end)>0) {
			throw new IllegalArgumentException();
		}
		this.start = start;
		this.end = end;
		this.name = name;
	}

	public Date getStart() {
		return start;
	}

	public Date getEnd() {
		return end;
	}

	public int getName() {
		return name;
	}

	@Override
	public String toString() {
		return "SafeMain [start=" + start + ", end=" + end + ", name=" + name
				+ "]";
	}
}

 但是可能存在如下的攻击

	public static void main(String[] args) {
		//TOCTOU 
		//1
		Date start = new Date();
		Date end = new Date();
		int name = 111;
		SafeMain safeMain = new SafeMain(start, end,name);
		end.setYear(78);
		name = 23456;
		System.out.println(safeMain.getEnd().getYear());
		System.out.println(safeMain.toString());
		
		//2
		safeMain.getEnd().setYear(888);
	}

 最开始的设计是end大于start才满足要求.而且这里的start和end都是不可变的(按照原始的累的设计的要求是这样的),这2中攻击都使类的设计失效.

修正之后的类

public final class SafeMain {
	
	private final Date start;
	
	private final Date end;
	
	private final int name;
	
	public SafeMain(Date start,Date end,int name){
		this.start = start;
		this.end = end;
		this.name = name;
		if (this.start.compareTo(this.end)>0) {
			throw new IllegalArgumentException();
		}
	}

	public Date getStart() {
		return new Date(start.getTime());
	}

	public Date getEnd() {
		return new Date(end.getTime());
	}

	public int getName() {
		return name;
	}

	@Override
	public String toString() {
		return "SafeMain [start=" + start + ", end=" + end + ", name=" + name
				+ "]";
	}
}

 完美的避免了攻击

不止是在不可变的类的设计中这样保护性拷贝属性,某一些类的属性有一定的限制,在被后面的程序修改之后会产生不可预计的错误,也可以这样做.

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    深入理解java构造器机理

    “深入理解Java构造器机理” 在 Java 编程语言中,构造器是一...构造器是 Java 类中最重要的一个概念,用于初始化对象的创建。了解构造器的机理、执行顺序、作用及与其他概念的区别对于 Java 学习者和开发者非常重要。

    Effective Java读书笔记.pdf

    Effective Java是一本关于Java编程语言的经典书籍,本笔记主要总结了Java语言的发展历程、静态工厂方法的应用、构造器模式的使用等重要知识点。 一、Java语言的发展历程 Java语言的发展可追溯到1991年,当时由...

    Effective Java第三版1

    3. **单例模式**:通过私有构造器和枚举类型强化单例属性,确保线程安全且防止反射攻击。 4. **不可实例化**:使用私有构造器可以强化一个类只能通过特定方式(如静态方法)访问的特性。 5. **依赖注入**:推荐使用...

    java 构造器的调用

    - 如果一个类没有声明任何构造器,Java会自动提供一个无参的默认构造器。这个构造器不执行任何初始化操作,仅调用超类的默认构造器。 - 一旦为类定义了构造器,Java将不再提供默认构造器。因此,如果需要无参构造...

    effective-java.pdf

    标题“effective-java.pdf”与描述“effective-java.pdf”表明本文档是关于Java编程实践的指南,且内容可能来自于一本名为《Effective Java》的书籍,该书是由Joshua Bloch编写,被广泛认为是Java编程的权威指南。...

    effectiveJava课件分享

    在编程领域,特别是Java开发中,"Effective Java"是一本非常经典的书籍,由Joshua Bloch撰写,书中提出了一系列最佳实践和设计原则,以帮助开发者编写出更高效、更安全的代码。根据提供的标题和描述,我们将探讨三个...

    Java入门理解构造器

    - **默认构造器**:当一个类没有显式地定义任何构造器时,Java编译器会自动为该类提供一个默认构造器。默认构造器是无参的,并且不执行任何操作。 - **自定义构造器**:开发者可以根据需求定义一个或多个构造器来...

    《Effective Java》读书分享.pptx

    通过私有构造器强化不可实例化的能力,可以防止工具类被实例化。 Builder 模式 Builder 模式是一种构建对象的方法,不直接生成想要的对象,而是利用必要参数调用构造器(或者静态工厂)得到一个 builder 对象,...

    effective java 读书笔记

    《Effective Java》是Java开发领域的经典著作,作者Joshua Bloch深入浅出地阐述了编写高效、健壮的Java代码的技巧和最佳实践。以下是对该书部分内容的详细解释: 1. **产生和销毁对象** - Item1:静态工厂方法相比...

    对象和构造器

    在 Java 程序设计中,对象和构造器是两个基本概念。对象是类的实例,构造器是创建对象的特殊方法。 类和对象 在 Java 中,每个对象都是一个类的实例。类是对对象的抽象,定义了对象的属性和行为。类中定义的变量...

    Effective Java.zip

    - 并发工具类:介绍了`java.util.concurrent`包中的线程安全类,如`ExecutorService`、`Semaphore`和`CountDownLatch`等。 - 线程安全的类设计:讲解了如何设计线程安全的类,包括同步方法、原子变量和线程局部...

    Effective java 3 学习记录.docx

    Effective Java 3 学习记录 本学习记录主要介绍了 Effective Java 3 中的静态工厂方法和 Builder 模式两部分内容。 一、静态工厂方法 静态工厂方法是指返回类实例的命名规则,例如:from、of、valueOf、instance ...

    effective-java 配套代码

    《Effective Java》是Java开发领域的一本经典著作,由Joshua Bloch撰写,书中提出了一系列编程最佳实践和设计模式,帮助开发者写出更高效、更可靠、更易于维护的Java代码。配套代码`effective-java-examples-master`...

    JAVA构造器

    JAVA构造器

    Java面向对象(基础)- 类的成员之三:构造器(Constructor)

    【Java面向对象(基础)- 类的成员之三:构造器(Constructor)】 构造器是Java中用于初始化新创建对象的特殊方法。当我们使用`new`关键字创建一个对象时,构造器会被自动调用,用于设置对象的初始状态。构造器的名字...

    effectiveJava的笔记

    2. **构造器与工厂方法**:提倡使用私有构造器和静态工厂方法,以便于控制类的实例化过程,提高代码灵活性,例如实现不可变对象、延迟初始化等。 3. **接口与抽象类**:讨论了接口和抽象类在设计上的差异,强调接口...

Global site tag (gtag.js) - Google Analytics