java 继承 扩展_Java继承,扩展类如何影响实际的类

我正在审核《 Sun认证研究指南》,其中有一段描述了最终修饰符。 它说

"如果程序员自由扩展String类文明,因为我们知道它可能崩溃"

他什么意思 ?

如果可以扩展String Class ...,我只是没有一个名为MyString的类,该类继承了所有Strings属性。

仅通过扩展它,怎么可能以任何方式更改实际的String类?

非常感谢您的回答

听起来有点夸张

@mre是的,但是非常棒,因此在认证考试中已经给出了!

@drlobo我认为您应该将此问题的标题更改为:"为什么Sun认证研究指南认为扩展String类会导致文明崩溃?"

您可以添加一个链接吗?

可能有重复的理由禁止Java继承?

嗯,一个问题是,如果可以继承String类,则很可能会以多种方式破坏jvm的安全性。许多权限会检查各种String值,以确定是否允许给定的操作。如果您的代码提供了字符串值,则可以返回一个String实例,当安全管理器查看该实例时,该实例"签出",但以后的行为就像一个完全不同的值。

例如,假设您有一些敏感的jvm范围的配置:

public static void registerProvider(String providerName, Provider impl) {

SecurityManager sm = ...;

if(sm != null) {

// say the check provider method doesn't allow strings starting with"com.sun."

sm.checkProvider(providerName);

}

_providerMap.put(providerName, impl);

}

现在,我实现了一个自定义String,如果传递了值"com.sun.",它将覆盖startsWith()方法以返回false,但是我的String的实际值确实以com.sun.开头。

当然,更不用说String的一般期望是不可变的,如果将其破坏,可能会引起各种普遍的破坏(如在其他答案中更详细提到的)。

您称这个为ChuckNorrisString吗?:-)

虽然,按照我的想法,ChuckNorrisString会覆盖hashCode():您将其放在地图中,然后稍后再查找时,它不在那儿。

@kdgregory-ChuckNorrisString不会非常有用,因为它永远不会等于任何东西。 并对其进行排序很困难,因为它总是比其他所有东西都大。

打的好。 (您是否知道不能使用空格来填写15个字符的最小注释长度?)

扩展类不会影响基类。但是,它可能会影响基类的使用者。

因此,假设您能够扩展String,则可以编写如下内容:

class MyString extends String {

@Override

public int length() {

System.exit();

}

}

现在,您将该类传递给使用字符串的任何内容,并且很有可能会迅速退出程序。这不是文明的终结,但是您可以做更多险恶的事情。

考虑到整个Java API,您将看到如下结构:

HashMap map;

使用字符串进行索引。很常见的事情,例如财产和-在与安全相关的地方,这可能是最糟糕的情况。此代码依靠未经修改的String保持安全。

但是现在让您修改后的String类允许例如原位反转弦。

然后我们所知道的世界将会崩溃,因为整个地方的地图都会变得一团糟。记录会崩溃等。

很多代码依赖String类是不可变的,并且,如果它确实是不可变的,那么您想在其上添加什么功能?

更改行为一定不能使不变性约束无效。 考虑具有方便构造函数的类ReversedString。

@jeppi您可以使用静态方法简单地进行替换,实际上完全不需要新类。

在某些情况下,与静态工厂方法相比,您更喜欢构造函数。 也许ReversedString不是最现实的例子。 只是在那里谈论不可变的物体...

扩展类完全不会影响该类。但是,由于任何继承的类也是基类,因此它应遵守基类的行为契约。如果程序员要更改常见的框架类型,那么您就不能指望这些类能够按预期工作。因此,您要防止滥用此类的选项-使用final关键字即可完成

实际上,问题与扩展String或与此相关的任何其他类无关。

实际上,问题出在Java本身。问题是您实际上无法在其代码中定义特定对象实现的合同。实际上,在String的代码中并未指出它是不可变的,因为无法指定不可变性,只能对其进行编码。该合同仅来自String的实际实现。

如果可以用Java语言声明String,Number和Integer等是不可变的,那么我们就不必将这些类设置为final。我认为这是Java的衰弱病,您无法在代码中定义合同。您只能对其进行编码和记录。

我希望能够扩展字符串并定义UppercaseString extends String,但是Java中没有contract(immutable,interned)关键字,所以我不能这样做,因为为了与该合同最接近,唯一可用的关键字是final而不是应该的immutable。

僵化的夸张可能是对String(im)可变性的安全性方面的暗示。字符串通常作为参数传递给各种I / O资源连接API(例如JDBC和File I / O)。这样的字符串通常是资源定位符和身份验证凭据的串联,并且该API将在返回连接之前执行检查以确保凭据对所请求的资源有效。如果String是可变的,那么它将在身份验证成功后修改资源指针/地址(例如,用于数据库连接的数据库名称或包含用户敏感信息的文件名),从而打开各种安全漏洞的网关。但是在为请求的原始资源建立资源连接之前,会导致未经授权的访问和破坏访问控制。

使String不可变的另一个原因是使其成为线程安全的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值