我可以在Java的String类中添加新方法吗?

时间:2020-03-05 18:58:30  来源:igfitidea点击:

我想将方法​​AddDefaultNamespace()添加到Java中的String类中,以便我可以键入" myString" .AddDefaultNamespace()而不是DEFAULTNAMESPACE +" myString",以获得类似于" MyDefaultNameSpace.myString"的名称。我也不想添加另一个派生类(例如PrefixedString)。

也许这种方法对我们不利,但我个人讨厌使用" +"。但是,无论如何,是否有可能向Java中的String类添加新方法?

谢谢并恭祝安康。

解决方案

回答

字符串是最后一个类,这意味着它不能扩展为可以在我们自己的实现上工作。

回答

这是不可能的,因为String是Java中的最终类。

我们可以随时使用辅助方法作为前缀。如果我们不喜欢,可以考虑使用Groovy或者Scala,JRuby或者JPython都是与Java兼容的JVM的语言,并允许此类扩展。

回答

不可能的,那是一件好事。字符串是字符串。它的行为是定义好的,背离它是邪恶的。另外,它被标记为final,这意味着即使我们愿意也不能将其子类化。

回答

最好使用StringBuilder,它具有方法append()并完成所需的工作。 String类是最终的,不能扩展。

回答

类声明几乎说明了所有内容,因为我们不能继承它,因为它是最终的。
我们当然可以实现自己的字符串类,但这很麻烦。

public final class String

C(.net 3.5)具有使用扩展程序方法的功能,但可惜的是Java没有。有一些Java扩展名为nice http://nice.sourceforge.net/,尽管这似乎为Java添加了相同的功能。

这是我们使用尼斯语言编写示例的方式(
Java):

private String someMethod(String s)
{
   return s.substring(0,1);

}

void main(String[] args)
{
   String s1 = "hello";
   String s2 = s1.someMethod();
   System.out.println(s2);

}

我们可以在http://nice.sf.net上找到有关尼斯的更多信息。

回答

Java String类是最终的,使其不可变。这是出于效率方面的考虑,并且很难在逻辑上进行扩展而不会出现错误;因此,实现者选择将其设为最终类,这意味着无法通过继承对其进行扩展。

根据单职责原则,我们希望类支持的功能不是String的常规职责的适当组成部分,它是名称空间,它是不同的抽象,更专门。因此,我们应该定义一个新类,其中包括String成员,并支持提供所需名称空间管理所需的方法。

不要害怕添加抽象(类),这些是好的OO设计的本质。

尝试使用类责任协作(CRC)卡来阐明所需的抽象。

回答

我们可以创建自己的String类版本并添加方法:-)

回答

实际上,我们可以修改String类。如果我们编辑src.zip中的String.java文件,然后重建rt.jar,则String类将为我们添加更多方法。不利之处在于该代码仅在计算机上可用,或者如果我们提供String.class并将其放在默认代码之前的classpath中,则该代码将只适用于计算机。

回答

就像其他人都说过的那样,不可以将String归类,因为它是最终的。但是,以下内容可能会有所帮助吗?

public final class NamespaceUtil {

    // private constructor cos this class only has a static method.
    private NamespaceUtil() {}

    public static String getDefaultNamespacedString(
            final String afterDotString) {
        return DEFAULT_NAMESPACE + "." + afterDotString;
    }

}

或者许:

public final class NamespacedStringFactory {

    private final String namespace;

    public NamespacedStringFactory(final String namespace) {
        this.namespace = namespace;
    }

    public String getNamespacedString(final String afterDotString) {
        return namespace + "." + afterDotString;
    }

}

回答

正如其他所有人都指出的那样,不允许扩展String(由于final)。但是,如果我们感觉很疯狂,则可以修改String本身,将其放在jar中,并在bootclasspath之前加上-Xbootclasspath / p:myString.jar以实际替换内置的String类。

由于我不愿讨论的原因,实际上我之前已经做过。我们可能想知道,即使我们可以替换该类,但String在Java各个方面的内在重要性意味着它在整个JVM启动期间都被使用,并且某些更改只会破坏JVM。添加新方法或者构造函数似乎没有问题。添加新字段非常麻烦,特别是添加对象或者数组似乎会破坏事情,尽管添加原始字段似乎可行。

回答

所有其他贡献者之前都说过。我们不能直接扩展String,因为它是最终的。

如果要使用Scala,则可以使用如下隐式转换:

object Snippet {
  class MyString(s:String) {
    def addDefaultNamespace = println("AddDefaultNamespace called")
  }
  implicit def wrapIt(s:String) = new MyString(s)

  /** test driver */
  def main(args:Array[String]):Unit = {
    "any java.io.String".addDefaultNamespace // !!! THAT is IT! OR?
  }