views:

411

answers:

8

I need to create a class with exactly the same methods as java.lang.String.

What is the best way to do this in Java?

I know that I can't extend String class as it is final. I am not looking at solutions where I need to copy the source code of java.lang.String. For example, assume that I need the functionality length() within my custom class named MyString, which has a corresponding 'myLength()` method.

What is the best way to implement myLength()?

I am not looking at various algorithms to find out the length of a string but to reuse String's length() method. Now once I have MyString class ready, I should be able to use it anywhere for my custom manipulations.

+2  A: 

Make a new class (it will need a different package, of course, implement the same interface and add all the public methods from the String class (read the javadoc to make sure you got everything).

I have to assume this is homework.

Yishai
+5  A: 

Since final classes cannot be subclassed, create a new class that has a String instance inside and operate on this object.

public class MyString {
  private String s;

  public MyString( String s ) {
    setInternalString( s );
  }

  public int myLength() {
    return getInternalString().length();
  }

  private void setInternalString( String s ) {
    this.s = s;
  }

  private String getInternalString() {
    return this.s == null ? "" : this.s;
  }
}
TBH
Called delegation.
Dave Jarvis
+3  A: 

I assume you mean java.lang.String. However, you can't replace String with your own class. You can make another class with the same methods (by copying the source code and changing the package declaration), but you won't be able to pass instances of that class to methods that require a String.

Which brings up an important question: why do you think you want to do this?

erickson
I do not want to create a class just by copying all the methods from String class. This question was asked to me in an interview.
Harsha
Maybe it was a trick question, and you were supposed to explain to them why doing this would prevent you from inter-operating with almost ever existing Java API.
erickson
Another answer to the interview would be point out that String implements CharSequence and you can create other implementations. Of course, that doesn't help if the APIs that use the ersatz string require a String rather than a CharSequence.
Stephen C
A: 

If you just want to override a portion of the String behaviour you could try using a dynamic proxy. Look up java.lang.reflect.Proxy in the API.

BigMikeW
The built-in dynamic proxy support only works with interfaces. ASM and other bytecode libraries can work with classes, but I'm not sure about final classes.
erickson
+2  A: 

Proxy design pattern, I guess. It's a stupid question, though (not a reflection on the asker, but on the person that asked him it in a job interview). Possibly the person asking you didn't realise that String is final? Otherwise I can't think why they would even ask.

ZoFreX
I think the real challenge lies in the fact that the String is final. Otherwise the answer is pretty simple isnt it? Just extend String and you are done with.
Harsha
+3  A: 

From your question it sounds like the thing you are looking for is simple delegation:

class MyString {

  String delegate; // The actual string you delegate to from your class

  public MyString(String delegate) {
    this.delegate = delegate; // Assign the string that backs your class
  }

  int length() {
    return delegate.length(); // Delegate the method call to the string
  }

  // other methods that delegate to the string field
}
Fabian Steeg
This looks good. But can I do MyString strAbc = "This is my String" ?I am looking for an exact replica of String. In your solution, I would need to pass the String in the constructor.
Harsha
@ Harsha, what you want is simply not possible.
Paul Wagland
@Paul Can you please explain?
Harsha
@Harsha, I added an answer to explain more fully than these comments allow.
Paul Wagland
@Paul: Thanks Paul.
Harsha
@Harsha no problems... if it is helpful, and upvote is always nice ;-)
Paul Wagland
@Paul: Unfortunately I have reached my daily quota of upvotes. I would surely upvote it tomorrow.
Harsha
+1  A: 
OscarRyz
+2  A: 

Going through the various answers here, and the askers updates and clarifications, it appears that what the asker wants is a class that looks, smells and sounds like a String, but is not.

That is they would like to be able to do:

MyString string = "String!!";

This cannot work, since java.lang.String is a final class, and so every "String" that the compiler produces will be a java.lang.String object, since this is not a MyString object they cannot be assigned to each other.

In weakly typed languages you would be able to create such a class, since if a class looks, smells and sounds like a duck, then to all intents and purposes, it is a duck. Java, however, is a strongly typed language, and a duck is only a duck if it happens to be from the Anatidae family of birds.

Paul Wagland