tags:

views:

2999

answers:

16

Hello,

I'd like to add a method AddDefaultNamespace() to the String class in Java so that I can type "myString".AddDefaultNamespace() instead of DEFAULTNAMESPACE + "myString", to obtain something like "MyDefaultNameSpace.myString". I don't want to add another derived class either (PrefixedString for example).

Maybe the approach is not good for you but I personally hate using "+". But, anyway, is it possible to add new methods to the String class in Java?

Thanks and regards.

+12  A: 

String is a final class means it cannot be extended to work on your own implementation.

GustlyWind
Simple and clear. Thanks GustlyWind and the rest of you.
A: 

No, this isn't possible in pure java

If you use something like Groovy, or JRuby you can do it however

tim_yates
A: 

No, you can't.

EricSchaefer
+3  A: 

It is not possible, since String is a final class in Java.

You could use a helper method all the time you want to prefix something. If you don't like that you could look into Groovy or Scala, JRuby or JPython both are languages for the JVM compatible with Java and which allow such extensions.

jrudolph
A: 

Not possible, and that's a good thing. A String is a String. It's behaviour is defined, deviating from it would be evil. Also, it's marked final, meaning you couldn't subclass it even if you wanted to.

Sietse
A: 

Better use StringBuilder, which has method append() and does the job you want. The String class is final and can not be extended.

m_pGladiator
A: 

adimit is wrong...

"test".length() ;

is a perfectly valid bit of Java

tim_yates
+2  A: 

The class declaration says it all pretty much,as you cannot inherit it becouse it's final. You can ofcourse implement your own string-class, but that is probaby just a hassle.

public final class String

C# (.net 3.5) have the functionality to use extender metods but sadly java does not. There is some java extension called nice http://nice.sourceforge.net/ though that seems to add the same functionality to java.

Here is how you would write your example in the Nice language (an extension of 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);

}

You can find more about Nice at http://nice.sf.net

Carl-Johan
A: 

String is a final class, making it immutable. The Java String class is immutable for efficiency reasons. Also it would be extremely difficult to logically extend without error; the implementers have therefore chosen to make it a final class meaning it cannot be extended with inheritance.

The functionality you wish your class to support is not properly part of the responsibilities of String, it is a different abstraction. You should therefore define a new class, which includes a String member and supports the methods you need to provide the namespace management functions you require.

Do not be afraid to add abstractions (classes) these are the essence of good OO design.

Try using a class responsibility collaboration (CRC) card to clarify the abstraction you need.

Martin Spamer
A: 

You can create your own version of String class and add a method :-)

A: 

Actually , you can modify the String class . If you edit the String.java file located in src.zip , and then rebuild the rt.jar , the String class will have more methods added by you . The downside is that that code will only work on your computer , or if you provide your String.class , and place it in the classpath before the default one .

Vhaerun
A: 

Not in Java. Other JVM languages such as jruby can. Scala can also do it with implicit conversions (compile time).

Michael Neale
+1  A: 

As everybody else has said, no you can't subclass String because it's final. But might something like the following help?

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

}

or maybe:

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

}
MB
+2  A: 

As everyone else has noted, you are not allowed to extend String (due to final). However, if you are feeling really wild, you can modify String itself, place it in a jar, and prepend the bootclasspath with -Xbootclasspath/p:myString.jar to actually replace the built-in String class.

For reasons I won't go into, I've actually done this before. You might be interested to know that even though you can replace the class, the intrinsic importance of String in every facet of Java means that it is use throughout the startup of the JVM and some changes will simply break the JVM. Adding new methods or constructors seems to be no problem. Adding new fields is very dicey - in particular adding Objects or arrays seems to break things although adding primitive fields seems to work.

Alex Miller
A: 

For security and efficiency reason this would be bad and Java doesn't allow adding methods to a class externally anyway.

James A. N. Stauffer
A: 

All is said by the other contributors before. You can not extend String directly because it is final.

If you would use Scala, you can use implicit conversions like this:

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