¿Puedo agregar nuevos métodos a la clase String en Java?

Me gustaría agregar un método AddDefaultNamespace () a la clase String en Java para poder escribir “myString” .AddDefaultNamespace () en lugar de DEFAULTNAMESPACE + “myString”, para obtener algo como “MyDefaultNameSpace.myString”. No quiero agregar otra clase derivada tampoco (PrefixedString por ejemplo).

Quizás el enfoque no sea bueno para ti, pero personalmente odio usar “+”. Pero, de todos modos, ¿es posible agregar nuevos métodos a la clase String en Java?

Gracias y saludos.

String es una clase final, lo que significa que no se puede extender para que funcione en su propia implementación.

Bueno, en realidad todo el mundo está falto de imaginación. Necesitaba escribir mi propia versión del método startsWith porque necesitaba una que no distinga mayúsculas de minúsculas.

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

Entonces es bastante simple, haces tu String como tal:

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

y cuando necesite llamar a un método en la biblioteca String, simplemente haga lo siguiente:

 StringOne.str.equals(""); 

o algo similar, y ahí lo tienes … extensión de la clase String.

Como todos los demás han notado, no está permitido extender String (debido a la final). Sin embargo, si se siente realmente salvaje, puede modificar String, colocarlo en un jar y anteponer el bootclasspath con -Xbootclasspath / p: myString.jar para reemplazar realmente la clase String incorporada.

Por razones que no entraré, lo he hecho antes. Puede que le interese saber que, aunque puede reemplazar la clase, la importancia intrínseca de String en todas las facetas de Java significa que se usa durante el inicio de la JVM y algunos cambios simplemente romperán la JVM. Agregar nuevos métodos o constructores parece no ser un problema. Agregar nuevos campos es muy arriesgado; en particular, agregar objetos o matrices parece romper las cosas, aunque parece que el agregado de campos primitivos funciona.

No es posible, ya que String es una clase final en Java.

Puede usar un método de ayuda todo el tiempo que quiera prefijar algo. Si no le gusta, puede buscar en Groovy o Scala, JRuby o JPython son idiomas para la JVM compatible con Java y que permiten dichas extensiones.

La statement de la clase lo dice todo, ya que no puedes heredarlo porque es definitivo. Por supuesto, puede implementar su propia clase de cadena, pero eso es probablemente una molestia.

 public final class String 

C # (.net 3.5) tiene la funcionalidad de usar extensores, pero lamentablemente java no. Hay alguna extensión java llamada nice http://nice.sourceforge.net/ aunque parece que agrega la misma funcionalidad a java.

Así es como escribirías tu ejemplo en el lenguaje de Niza (una extensión de 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); } 

Puede encontrar más acerca de Niza en http://nice.sf.net

No es posible, y eso es algo bueno. Una cadena es una cadena. Su comportamiento está definido, desviarse de él sería malo. Además, está marcado como final, lo que significa que no podrías subclasificarlo aunque quisieras.

Como todos han dicho, no, no se puede subclase String porque es final. Pero podría algo como la siguiente ayuda?

 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; } } 

o tal vez:

 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; } } 

Mejor use StringBuilder, que tiene el método append () y hace el trabajo que desea. La clase String es final y no se puede extender.

Las personas que buscan con palabras clave “agregar método a la clase incorporada” pueden terminar aquí. Si está buscando agregar un método a una clase no final como HashMap, puede hacer algo como esto.

 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); } } 

Ahora defina una nueva instancia de esta clase como:

 ObjectMap objectMap = new ObjectMap(new HashMap(); 

Ahora puede acceder a todos los métodos de la clase Map integrada y también a los métodos recientemente implementados.

 objectMap.getInt("KEY"); 

EDITAR:

En el código anterior, para acceder a los métodos integrados de la clase de mapa, tendrías que usar

 objectMap.map.get("KEY"); 

Aquí hay una solución aún mejor:

 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; } } 

Ahora no tienes que llamar

 objectMap.map.get("KEY"); 

simplemente llame

 objectMap.get("KEY"); 

No, no puedes modificar la clase de cadena en java. Porque es la clase final. y cada método presente en la clase final por defecto será final.

La razón más importante por la que String es inmutable o definitiva es que es utilizada por el mecanismo de carga de clases y, por lo tanto, tiene aspectos de seguridad fundamentales y profundos.

Si String hubiera sido mutable o no final, una solicitud para cargar “java.io.Writer” podría haberse cambiado para cargar “mil.vogoon.DiskErasingWriter”

¡SÍ!

En función de sus requisitos (agregue un espacio de nombres diferente a una Cadena y no use una clase derivada) podría usar el proyecto Lombok para hacer eso y usar la funcionalidad en una Cadena como esta:

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

Usando la idea de Gradle y IntelliJ siga los pasos a continuación:

  1. Descargue el complemento lombok desde el repository de complementos de intelliJ.
  2. agregue lombok a dependencias en gradle como tal: compileOnly 'org.projectlombok:lombok:1.16.20'
  3. vaya a "Settings > Build > Compiler > Annotation Processors" y habilite el procesamiento de anotación
  4. crea una clase con tus funciones de extensión y agrega un método estático como este:

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

  5. anota la clase en la que quieres usar tu método así:

    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()); } }

Ahora puede usar el método .appendSize() en cualquier cadena de cualquier clase, siempre que lo haya (anotado) y el resultado producido para el ejemplo anterior (This is a String!) Sería: ¡ This is a String! 17 This is a String! 17

Todo lo dicho por los otros colaboradores antes. No puede extender String directamente porque es final.

Si usa Scala, puede usar conversiones implícitas como esta:

 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? } 

La clase Java String es una final, por lo que es inmutable. Esto es por razones de eficiencia y que sería extremadamente difícil extender lógicamente sin error; los implementadores, por lo tanto, han elegido convertirlo en una clase final, lo que significa que no se puede extender con la herencia.

La funcionalidad que desea que su clase soporte no es propiamente parte de las responsabilidades regulares de un String según el principio de responsabilidad única , un espacio de nombres es una abstracción diferente, es más especializado. Por lo tanto, debe definir una nueva clase, que incluye un miembro de String y admite los métodos que necesita para proporcionar la administración de espacio de nombres que necesita.

No tengas miedo de agregar abstracciones (clases) estas son la esencia del buen diseño OO.

Intente utilizar una tarjeta de colaboración de responsabilidad de clase (CRC) para aclarar la abstracción que necesita.

Puedes crear tu propia versión de la clase String y agregar un método 🙂

En realidad, puedes modificar la clase String. Si edita el archivo String.java ubicado en src.zip, y luego reconstruye el rt.jar, la clase String tendrá más métodos agregados por usted. La desventaja es que ese código solo funcionará en su computadora, o si proporciona su String.class, y lo coloca en el classpath antes del predeterminado.