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