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

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

Can I add new methods to the String class in Java?

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

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

谢谢并恭祝安康。


String是最终类,这意味着它不能扩展为在您自己的实现上工作。


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

1
2
3
4
5
6
7
class MyString{
    public String str;
    public MyString(String str){
        this.str = str;
    }
    // Your methods.
}

然后,这很简单,您可以将String设置为:

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

当您需要在String库中调用方法时,可以像这样简单地进行操作:

1
StringOne.str.equals("");

或类似的东西,就在那里...扩展String类。


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

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


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

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


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

1
public final class String

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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归类,因为它是最终的。但是,以下内容可能会有所帮助吗?

1
2
3
4
5
6
7
8
9
10
11
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;
    }

}

或许:

1
2
3
4
5
6
7
8
9
10
11
12
13
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,这意味着即使您愿意也不能将其子类化。


是!

根据您的要求(将不同的名称空间添加到String而不使用派生类),您可以使用项目Lombok做到这一点,并在String上使用功能,如下所示:

1
2
String i ="This is my String";
i.numberOfCapitalCharacters(); // = 2

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

  • 从intelliJ插件存储库下载lombok插件。
  • 将lombok添加到gradle中的依赖项中,如下所示:compileOnly 'org.projectlombok:lombok:1.16.20'
  • 转到"Settings > Build > Compiler > Annotation Processors"并启用注释处理
  • 使用扩展功能创建一个类,并添加一个静态方法,如下所示:

    1
    2
    3
    4
    5
    public class Extension {
        public static String appendSize(String i){
            return i +"" + i.length();
        }
    }
  • 在您想使用方法的地方注释类,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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


    否,您无法在Java中修改字符串类。因为这是最后一堂课。并且默认情况下,final类中存在的每个方法都是final。

    String不可更改或最终更改的绝对最重要的原因是它由类加载机制使用,因此具有深远的基础安全方面。

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


    用关键字"将方法添加到内置类"搜索的人们可能会在这里结束。如果要向非最终类(例如HashMap)添加方法,则可以执行以下操作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    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);
        }
    }

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

    1
    ObjectMap objectMap = new ObjectMap(new HashMap<String, Object>();

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

    1
    objectMap.getInt("KEY");

    编辑:

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

    1
    objectMap.map.get("KEY");

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    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;
        }
    }

    现在您不必打电话

    1
    objectMap.map.get("KEY");

    只需致电

    1
    objectMap.get("KEY");

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


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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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类是最终的,使其不可变。这是出于效率方面的考虑,并且很难在逻辑上进行扩展而不会出错。因此,实现者选择将其设为最终类,这意味着无法通过继承对其进行扩展。

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

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

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


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


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


    推荐阅读

      linux添加的命令保存?

      linux添加的命令保存?,系统,时间,地址,名字,命令,文件,工作,名称,文件名,文

      linux添加用户的命令?

      linux添加用户的命令?,密码,系统,软件,联系方式,用户,新增,信息,管理人员,

      linux添加网口命令?

      linux添加网口命令?,网络,系统,工具,信息,最新,设备,地址,工作,密码,数据,lin

      linux命令添加挂载点?

      linux命令添加挂载点?,系统,信息,名称,情况,电脑,名字,设备,磁盘,分区,命令,l

      linux添加端口命令?

      linux添加端口命令?,服务,系统,工具,端口,位置,情况,软件,对外开放,命令,文

      linux命令添加ip?

      linux命令添加ip?,地址,系统,代码,网络,服务,密码,命令,百度,工具,设备,Linux

      linux命令中添加用户?

      linux命令中添加用户?,系统,密码,软件,用户,命令,信息,目录,用户名,账号,文

      linux添加分辨率命令?

      linux添加分辨率命令?,系统,情况,分辨率,状态,屏幕分辨率,屏幕,命令,桌面,

      linux系统命令添加?

      linux系统命令添加?,系统,密码,代码,简介,命令,实战,项目,工作,资料,基础,lin

      linux命令添加磁盘?

      linux命令添加磁盘?,系统,管理,信息,情况,电脑,数据,磁盘,命令,环境,工作,Lin

      添加网卡linux的命令?

      添加网卡linux的命令?,地址,系统,网络,信息,设备,电脑,网卡,发行,基本知识,

      linux新硬件添加命令?

      linux新硬件添加命令?,系统,设备,数据,业务,服务,盘前,信息,密码,名字,硬盘,

      添加网卡linux的命令?

      添加网卡linux的命令?,地址,系统,网络,信息,设备,电脑,网卡,发行,基本知识,

      linux新硬件添加命令?

      linux新硬件添加命令?,系统,设备,数据,业务,服务,盘前,信息,密码,名字,硬盘,

      linux命令添加一个组?

      linux命令添加一个组?,密码,系统,管理,代码,用户组,用户,命令,新增,文件,目

      linux添加快捷命令?

      linux添加快捷命令?,软件,名称,较大,第一,发行,命令,终端,快捷键,窗口,方法,

      linux命令添加文件?

      linux命令添加文件?,工作,简介,数据,系统,文件,命令,操作,文件名,内容,终端,l

      linux添加自启命令?

      linux添加自启命令?,服务,状态,密码,系统,脚本,第三,人员,标准,在线,实时,Pyt

      linux自启命令添加?

      linux自启命令添加?,服务,系统,工具,第三,第一,代码,密码,标准,项目,实时,lin

      linux使用命令的方法?

      linux使用命令的方法?,系统,信息,工具,标准,数据,命令,左下角,目录,文件夹,