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

我想在Java中的String类中添加一个方法AddDefaultNamespace(),这样我就可以输入“myString”.AddDefaultNamespace()而不是DEFAULTNAMESPACE +“myString”,以获得类似“MyDefaultNameSpace.myString”的内容。 我不想添加另一个派生类(例如PrefixedString)。

也许这种方法对你不好,但我个人讨厌使用“+”。 但是,无论如何,是否可以在Java中向String类添加新方法?

感谢致敬。

String是一个final类,这意味着它不能扩展为适合您自己的实现。

嗯,实际上每个人都缺乏想象力。 我需要编写自己的startsWith方法版本,因为我需要一个不区分大小写的方法。

 class MyString{ public String str; public MyString(String str){ this.str = str; } // Your methods. } 

然后它很简单,你就像这样制作你的字符串:

 MyString StringOne = new MyString("Stringy stuff"); 

当你需要在String库中调用一个方法时,这样做很简单:

 StringOne.str.equals(""); 

或类似的东西,你有它…扩展String类。

正如其他人都注意到的那样,你不能扩展String(由于最终)。 但是,如果您感觉非常狂野,可以修改String本身,将其放在jar中,并在-cbootclasspath / p:myString.jar之前添加bootclasspath以实际替换内置的String类。

由于我不会进入的原因,我之前实际上已经这样做了。 您可能有兴趣知道即使您可以替换该类,但在Java的每个方面,String的内在重要性意味着它在JVM的整个启动过程中使用,并且一些更改将简单地破坏JVM。 添加新方法或构造函数似乎没有问题。 添加新字段非常冒险 – 特别是添加对象或数组似乎会破坏事情,尽管添加原始字段似乎有效。

这是不可能的,因为String是Java中的最后一个类。

您可以随时使用辅助方法为前缀添加前缀。 如果您不喜欢它,您可以查看Groovy或Scala,JRuby或JPython都是与Java兼容的JVM的语言,并允许这样的扩展。

类声明说明了这一切,因为你不能inheritance它,因为它是最终的。 你可以实现自己的字符串类,但这可能只是一个麻烦。

 public final class String 

C#(。net 3.5)具有使用扩展器metods的function,但遗憾的是java没有。 有一些名为nice http://nice.sourceforge.net/的 java扩展,虽然它似乎为java添加了相同的function。

以下是如何使用Nice语言(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找到更多关于尼斯的信息

不可能,那是件好事。 String是一个String。 它的行为被定义,偏离它将是邪恶的。 此外,它标记为final,这意味着即使您想要也不能将其子类化。

正如其他人所说的那样,没有你不能将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; } } 

最好使用StringBuilder,它有方法append()并完成你想要的工作。 String类是final,无法扩展。

使用关键字“将方法添加到内置类中”的人可能会在这里结束。 如果您希望将方法添加到非最终类(如HashMap),则可以执行此类操作。

 public class ObjectMap extends HashMap { public Map map; public ObjectMap(Map map){ this.map = map; } public int getInt(String K) { return Integer.valueOf(map.get(K).toString()); } public String getString(String K) { return String.valueOf(map.get(K)); } public boolean getBoolean(String K) { return Boolean.valueOf(map.get(K).toString()); } @SuppressWarnings("unchecked") public List getListOfStrings(String K) { return (List) map.get(K); } @SuppressWarnings("unchecked") public List getListOfIntegers(String K) { return (List) map.get(K); } @SuppressWarnings("unchecked") public List> getListOfMapString(String K) { return (List>) map.get(K); } @SuppressWarnings("unchecked") public List> getListOfMapObject(String K) { return (List>) map.get(K); } @SuppressWarnings("unchecked") public Map getMapOfObjects(String K) { return (Map) map.get(K); } @SuppressWarnings("unchecked") public Map getMapOfStrings(String K) { return (Map) map.get(K); } } 

现在将此类的新实例定义为:

 ObjectMap objectMap = new ObjectMap(new HashMap(); 

现在,您可以访问内置Map类的所有方法,以及新实现的方法。

 objectMap.getInt("KEY"); 

编辑:

在上面的代码中,为了访问map类的内置方法,你必须使用

 objectMap.map.get("KEY"); 

这是一个更好的解决方案:

 public class ObjectMap extends HashMap { public ObjectMap() { } public ObjectMap(Map map){ this.putAll(map); } public int getInt(String K) { return Integer.valueOf(this.get(K).toString()); } public String getString(String K) { return String.valueOf(this.get(K)); } public boolean getBoolean(String K) { return Boolean.valueOf(this.get(K).toString()); } @SuppressWarnings("unchecked") public List getListOfStrings(String K) { return (List) this.get(K); } @SuppressWarnings("unchecked") public List getListOfIntegers(String K) { return (List) this.get(K); } @SuppressWarnings("unchecked") public List> getListOfMapString(String K) { return (List>) this.get(K); } @SuppressWarnings("unchecked") public List> getListOfMapObject(String K) { return (List>) this.get(K); } @SuppressWarnings("unchecked") public Map getMapOfObjects(String K) { return (Map) this.get(K); } @SuppressWarnings("unchecked") public Map getMapOfStrings(String K) { return (Map) this.get(K); } @SuppressWarnings("unchecked") public boolean getBooleanForInt(String K) { return Integer.valueOf(this.get(K).toString()) == 1 ? true : false; } } 

现在你不必打电话

 objectMap.map.get("KEY"); 

简单地打电话

 objectMap.get("KEY"); 

不,你不能在java中修改字符串类。 因为它是最后一堂课。 默认情况下,最终课程中的每个方法都是最终的。

String是不可变的或最终的绝对最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全方面。

如果String是可变的或不是最终的,加载“java.io.Writer”的请求可能已被更改为加载“mil.vogoon.DiskErasingWriter”

是!

根据您的要求 (向String添加不同的命名空间而不使用派生类),您可以使用项目Lombok来执行此操作并在String上使用function,如下所示:

 String i = “This is my String”; i.numberOfCapitalCharacters(); // = 2 

使用Gradle和IntelliJ想法请按照以下步骤操作:

  1. 从intelliJ plugins存储库下载lombok插件。
  2. 像这样在gradle中添加lombok到依赖项: compileOnly 'org.projectlombok:lombok:1.16.20'
  3. 转到"Settings > Build > Compiler > Annotation Processors"并启用注释处理
  4. 使用扩展函数创建一个类,并添加如下静态方法:

    public class Extension { public static String appendSize(String i){ return i + " " + i.length(); } }

  5. 注释要使用方法的类,如下所示:

    import lombok.experimental.ExtensionMethod; @ExtensionMethod({Extension.class}) public class Main { public static void main(String[] args) { String i = "This is a String!"; System.out.println(i.appendSize()); } }

现在你可以在任何类中的任何字符串中使用方法.appendSize() ,只要你有(注释它)和上面例子的生成结果(This is a String!)将是: This is a String! 17 This is a String! 17

之前其他贡献者都说过。 您不能直接扩展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? } 

Java String类是final,使其成为不可变的。 这是出于效率的原因,并且在没有错误的情况下逻辑扩展是非常困难的; 因此,实施者选择使其成为最终类,这意味着它不能通过inheritance来扩展。

根据单一责任原则 ,您希望您的类支持的function不是String的常规职责的正确部分,命名空间是不同的抽象,它更专业。 因此,您应该定义一个新类,其中包括String成员并支持您提供所需命名空间管理所需的方法。

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

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

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

实际上,您可以修改String类。 如果编辑位于src.zip中的String.java文件,然后重建rt.jar,则String类将添加更多方法。 缺点是该代码只能在您的计算机上运行,​​或者如果您提供String.class,并将其放在默认值之前的类路径中。