Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以在Java中向String类添加新方法吗?_Java_String - Fatal编程技术网

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

我可以在Java中向String类添加新方法吗?,java,string,Java,String,我想在Java中的String类中添加一个方法AddDefaultNamespace(),这样我就可以键入“myString.AddDefaultNamespace(),而不是DEFAULTNAMESPACE+“myString”,以获得类似于“MyDefaultNameSpace.myString”的内容。我也不想添加另一个派生类(例如,PrefixedString) 也许这种方法对你不好,但我个人讨厌使用+。但是,无论如何,是否可以在Java中向String类添加新方法 感谢和问候。Stri

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

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


感谢和问候。

String
是一个最终类,这意味着它不能扩展到您自己的实现。

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


您可以随时使用helper方法作为前缀。如果您不喜欢,您可以研究Groovy或Scala、JRuby或JPython这两种语言,它们都是与Java兼容的JVM语言,并且允许这样的扩展。

不可能,这是一件好事。字符串就是字符串。它的行为是有定义的,偏离它是邪恶的。此外,它被标记为final,这意味着您即使想对它进行子类化,也无法对其进行子类化。

最好使用StringBuilder,它具有方法append(),可以完成您想要的任务。String类是final,不能扩展。

类声明几乎说明了这一切,因为它是final,所以不能继承它。 当然,您可以实现自己的字符串类,但这可能只是一个麻烦

public final class String
C#(.NET3.5)具有使用扩展方法的功能,但遗憾的是java没有。有一个名为nice的java扩展,它似乎为java添加了相同的功能

下面是您如何用Nice语言编写示例(Nice语言的扩展 Java):


您可以在

上找到有关Nice的更多信息,Java字符串类是final,使其不可变。这是出于效率的原因,并且在逻辑上很难无误地扩展;因此,实现者选择将其作为最终类,这意味着它不能通过继承进行扩展

您希望您的类支持的功能不是字符串常规职责的一部分,因为名称空间是不同的抽象,它更专业。因此,您应该定义一个新类,该类包含一个成员字符串,并支持提供所需命名空间管理所需的方法

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


试着用a来澄清你需要的抽象

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

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

正如其他人所说,不,您不能对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;
    }

}

正如其他人所指出的,您不允许扩展字符串(由于final)。但是,如果您感觉非常疯狂,可以修改字符串本身,将其放在一个jar中,并在bootclasspath前面加上-Xbootclasspath/p:myString.jar以实际替换内置的字符串类


出于我不想讨论的原因,我以前确实做过这件事。您可能有兴趣知道,即使可以替换该类,字符串在Java的各个方面的内在重要性意味着它在JVM的整个启动过程中都会被使用,一些更改只会破坏JVM。添加新方法或构造函数似乎没有问题。添加新字段是非常危险的-特别是添加对象或数组似乎会破坏一些东西,尽管添加基本字段似乎是可行的

所有这些都是以前其他撰稿人说过的。不能直接扩展字符串,因为它是最终的

如果要使用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?
  }
StringOne.str.equals("");
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());
    }
}

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

class MyString{
    public String str;
    public MyString(String str){
        this.str = str;
    }
    // Your methods.
}
那么就很简单了,你把你的字符串变成这样:

MyString StringOne = new MyString("Stringy stuff");
当您需要调用字符串库中的方法时,可以这样做:

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?
  }
StringOne.str.equals("");
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());
    }
}

或者类似的东西,你有了它…字符串类的扩展。

用关键字“addmethodtobuildinclass”搜索的人可能会在这里结束。如果您希望将方法添加到非最终类(如HashMap)中,您可以这样做

public class ObjectMap extends HashMap<String, Object> {

    public Map<String, Object> map;

    public ObjectMap(Map<String, Object> 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<String> getListOfStrings(String K) {
        return (List<String>) map.get(K);
    }

    @SuppressWarnings("unchecked")
    public List<Integer> getListOfIntegers(String K) {
        return (List<Integer>) map.get(K);
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, String>> getListOfMapString(String K) {
        return (List<Map<String, String>>) map.get(K);
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> getListOfMapObject(String K) {
        return (List<Map<String, Object>>) map.get(K);
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> getMapOfObjects(String K) {
        return (Map<String, Object>) map.get(K);
    }

    @SuppressWarnings("unchecked")
    public Map<String, String> getMapOfStrings(String K) {
        return (Map<String, String>) map.get(K);
    }
}
编辑:

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

objectMap.map.get("KEY");
这里有一个更好的解决方案:

public class ObjectMap extends HashMap<String, Object> {

    public ObjectMap() {

    }

    public ObjectMap(Map<String, Object> 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<String> getListOfStrings(String K) {
        return (List<String>) this.get(K);
    }

    @SuppressWarnings("unchecked")
    public List<Integer> getListOfIntegers(String K) {
        return (List<Integer>) this.get(K);
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, String>> getListOfMapString(String K) {
        return (List<Map<String, String>>) this.get(K);
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> getListOfMapObject(String K) {
        return (List<Map<String, Object>>) this.get(K);
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> getMapOfObjects(String K) {
        return (Map<String, Object>) this.get(K);
    }

    @SuppressWarnings("unchecked")
    public Map<String, String> getMapOfStrings(String K) {
        return (Map<String, String>) this.get(K);
    }

    @SuppressWarnings("unchecked")
    public boolean getBooleanForInt(String K) {
        return Integer.valueOf(this.get(K).toString()) == 1 ? true : false;
    }
}
就叫

objectMap.get("KEY");

不,您不能在java中修改字符串类。因为这是最后一节课。默认情况下,final类中存在的每个方法都是final

字符串是不可变的或最终的最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全性

若字符串是可变的或不是最终的,则加载“java.io.Writer”的请求可能已更改为加载“mil.vogoon.DiskErasingWriter”

根据您的需求(向字符串添加不同的名称空间,而不是使用派生类),您可以使用project Lombok来实现这一点,并在字符串上使用如下功能:

String i = "This is my String";
i.numberOfCapitalCharacters(); // = 2
使用Gradle和IntelliJ idea,请遵循以下步骤:

  • 从intelliJ插件库下载lombok插件
  • 将lombok添加到gradle中的依赖项中,如下所示:
    compileOnly'org.projectlombok:lombok:1.16.20'
  • 转到
    “设置>生成>编译器>注释过程”
    
    public class Extension {
        public static String appendSize(String i){
            return i + " " + i.length();
        }
    }
    
    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());
        }
    }