-1

As we all know, String in java is final and immutable for the sake of security and performance. But, I wonder that is it possible to write a common mutable class MyString which can be modified and inherited? Eg:

public class MyString {
    private final char[] value;
    public void setChar(int index, char c){
        value[index] = c;
    }
}

--------UPDATE--------

I know there are a StringBuilder and StringBuffer and how they work. Here, I want to know that how java can ensure safe if I write my own MyString and use it everywhere I should use String. If I can do this, I think there is no insurance of safety. Is it?

expoter
  • 1,622
  • 17
  • 34
  • Have you looked at [`StringBuilder`](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)? – Elliott Frisch Jul 14 '16 at 03:24
  • http://stackoverflow.com/questions/25138587/what-is-difference-between-mutable-and-immutable-string-in-java – Jean-François Savard Jul 14 '16 at 03:25
  • 3
    *"write my own MyString and use it everywhere I should use String"* `String` is final and cannot be extended. Therefore it's impossible to create a class that is assignable to `String`. – fabian Jul 14 '16 at 03:33
  • you could use a StringBuilder and when you need to "use it as a String" call the toString method which would make a copy as a String - but if the question is really, can i pass my String into some API and change the contents "from the outside", the answer is no (even if you could, it would rarely be a good idea) – slipperyseal Jul 14 '16 at 04:15
  • What exactly is your concern? `MyString` is entirely unrelated to `String` - you can't pass a `MyString` to a method that expects a `String`, nor can you assign a `String` to a `MyString` variable. Sure, you could use `MyString` objects throughout your program, but why would anyone do that? It's like asking "Can I drive down the freeway backwards?" - well, yes, but why...... – dimo414 Aug 03 '16 at 18:18
  • @dimo414, I just want to know some internal mechanism about how jvm process String. – expoter Aug 04 '16 at 02:19
  • Here's the [source code for `String`](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/lang/String.java) - there's nothing special about it. The compiler processes string literals (e.g. `"text"`) into instances of `String` and it's not possible for you to change that behavior. – dimo414 Aug 04 '16 at 04:32

1 Answers1

1

You are right. If you create a MyString method and allow inheritance, your program is less safe then if you use the final immutable String class -- this is especially so if you fail to properly document the contract for Overriding methods. If your MyString is mutable, using your class may be even less desirable.

A primary example of an issue with inheritance occurs in the case of self-use of overridable methods. Consider the documentation for java.util.AbstractCollection::remove:

Removes a single instance of the specified element from this collection, if it is present (optional operation). More formally, removes an element e such that (o==null ? e==null : o.equals(e)), if this collection contains one or more such elements. Returns true if this collection contained the specified element (or equivalently, if this collection changed as a result of the call). This implementation iterates over the collection looking for the specified element. If it finds the element, it removes the element from the collection using the iterator's remove method.

The bolded section indicates that the method relies on the iterator method. The AbstractCollection class is designed for inheritance, so the documentation makes it clear that extending classes should consider overriding iterator() with care. Failing to document this behavior can lead to clients improperly overriding methods, which can lead to undefined behavior. Worse, if you define methods using MyString as an argument, a malicious user could pass in a subclass of MyString to further cause unexpected and potentially harmful changes to your system.

Mutability is desirable because it makes your program simpler to reason about. Critically immutable objects are inherently thread safe and can be shared easily. They also allow Strings to be cached for performance, but you knew about this.

So to answer your question: You can make a mutable, non-final MyString if you wish, but you cannot insure safety. You can only documented inheritance and hope users behave.

Source: My example was blatantly stolen from Joshua Bloch's Effective Java. Specifically item 15 (minimize mutability) and 17 (design and document for inheritance or else prohibit it) are good sources.

mkzh
  • 196
  • 1
  • 8