《Java编程思想第四版》学习笔记36--关于类克隆中的final关键字
  2BeoiZ3vpCmu 2023年11月02日 33 0

书中P.363有这样的说法:

......(6) 将类设为 final,从而防止克隆。......

......唯一安全的方法在ReallyNoMore 中得到了演示,它设为 final,所以不可继承。这意味着假如 clone()在 final 类中掷出了一个违例,便不能通过继承来进行修改,并可有效地禁止克隆(不能从一个拥有任意继承级数的类中明确调用Object.clone();只能调用 super.clone(),它只可访问直接基础类)。因此,只要制作一些涉及安全问题的对象,就最好把那些类设为 final。......

个人认为这个说法不对,原因如下:

1、final类不可继承,所以不存在子类的克隆问题;

2、如果从一个可克隆的类继承过来一个类,即使将该类设为final,仍然是可克隆的,可以用书上的例子CheckCloneable.java进行验证:

//: CheckCloneable.java
// Checking to see if a handle can be cloned
// Can't clone this because it doesn't
// override clone():
class Ordinary {}
// Overrides clone, but doesn't implement
// Cloneable:
class WrongClone extends Ordinary {
    public Object clone()
            throws CloneNotSupportedException {
        return super.clone(); // Throws exception
    }
}
// Does all the right things for cloning:
class IsCloneable extends Ordinary
        implements Cloneable {
    public Object clone()
            throws CloneNotSupportedException {
        return super.clone();
    }
}
// Turn off cloning by throwing the exception:
class NoMore extends IsCloneable {
    public Object clone()
            throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}
class TryMore extends NoMore {
    public Object clone()
            throws CloneNotSupportedException {
// Calls NoMore.clone(), throws exception:
        return super.clone();
    }
}
class BackOn extends NoMore {
    private BackOn duplicate(BackOn b) {
// Somehow make a copy of b
// and return that copy. This is a dummy
// copy, just to make the point:
        return new BackOn();
    }
    public Object clone() {
// Doesn't call NoMore.clone():
        return duplicate(this);
    }
}
// Can't inherit from this, so can't override
// the clone method like in BackOn:
final class ReallyNoMore extends NoMore {}
public class CheckCloneable {
    static Ordinary tryToClone(Ordinary ord) {
        String id = ord.getClass().getName();
        Ordinary x = null;
        if(ord instanceof Cloneable) {
            try {
                System.out.println("Attempting " + id);
                x = (Ordinary)((IsCloneable)ord).clone();
                System.out.println("Cloned " + id);
            } catch(CloneNotSupportedException e) {
                System.out.println(
                        "Could not clone " + id);
            }
        }
        return x;
    }
    public static void main(String[] args) {
// Upcasting:
        Ordinary[] ord = {
                new IsCloneable(),
                new WrongClone(),
                new NoMore(),
                new TryMore(),
                new BackOn(),
                new ReallyNoMore(),
        };
        Ordinary x = new Ordinary();
// This won't compile, since clone() is
// protected in Object:
//! x = (Ordinary)x.clone();
// tryToClone() checks first to see if
// a class implements Cloneable:
        for(int i = 0; i < ord.length; i++)
            tryToClone(ord[i]);
    }
} ///:~

在该例子中,如果从IsCloneable类继承过一个类,并将该类设为final,比如final class A extends IsCloneable {},A类仍然可克隆;如果把BackOn类加上final关键字(或者把ReallyNoMore类里加上类似BackOn的代码),BackOn(ReallyNoMore)仍然是可克隆的。

(在IntelliJ IDEA 2023.1.4 (Ultimate Edition),Java版本 "18.0.2" 2022-07-19环境下亲测过)


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  2Vtxr3XfwhHq   2024年05月17日   53   0   0 Java
  Tnh5bgG19sRf   2024年05月20日   109   0   0 Java
  8s1LUHPryisj   2024年05月17日   46   0   0 Java
  aRSRdgycpgWt   2024年05月17日   47   0   0 Java
2BeoiZ3vpCmu