背景

JavaのStringクラスはfinal型でスーパクラスにならなようになっている。

なぜJavaのクラスは拡張できないのか?

これは、書き換え可能になると、セキュリティ上の問題と、メモリの問題、同期の問題などいろいろと考える必要が出てくるからだそうだ。

わりとしっかりとした回答は下記のURLにありました。(英語)

http://javarevisited.blogspot.jp/2010/10/why-string-is-immutable-in-java.html

解決案

委譲パターンでそっくりなクラスを作ってみる。

デメリット

委譲パターンを使うデメリット 文字列だと""でインスタンスを作ることができた。 インスタンスを作ると、newしないといけなくなる。""でnewというシンタックスシューガーを手放すのはちょっと痛い。

メリット

拡張性を手に入れるということは、自分のニーズに合わせて進化させることができるということ。

領域は、メモリの消費を気にせず、セキュリティも気にせず、効率重視な作業に特化するとする作業領域はあるはずだ。要は使い分けが必要である。

Sクラスのソースコード

Stringクラスを委譲パターンで表現してみました。

package base;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Locale;

public class S {
	private String core;

	public int length() {
		return core.length();
	}

	public boolean isEmpty() {
		return core.isEmpty();
	}

	public char charAt(int index) {
		return core.charAt(index);
	}

	public int codePointAt(int index) {
		return core.codePointAt(index);
	}

	public int codePointBefore(int index) {
		return core.codePointBefore(index);
	}

	public int codePointCount(int beginIndex, int endIndex) {
		return core.codePointCount(beginIndex, endIndex);
	}

	public int offsetByCodePoints(int index, int codePointOffset) {
		return core.offsetByCodePoints(index, codePointOffset);
	}

	public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
		core.getChars(srcBegin, srcEnd, dst, dstBegin);
	}

	public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) {
		core.getBytes(srcBegin, srcEnd, dst, dstBegin);
	}

	public byte[] getBytes(String charsetName) throws UnsupportedEncodingException {
		return core.getBytes(charsetName);
	}

	public byte[] getBytes(Charset charset) {
		return core.getBytes(charset);
	}

	public byte[] getBytes() {
		return core.getBytes();
	}

	public boolean equals(Object anObject) {
		return core.equals(anObject);
	}

	public boolean contentEquals(StringBuffer sb) {
		return core.contentEquals(sb);
	}

	public boolean contentEquals(CharSequence cs) {
		return core.contentEquals(cs);
	}

	public boolean equalsIgnoreCase(String anotherString) {
		return core.equalsIgnoreCase(anotherString);
	}

	public int compareTo(String anotherString) {
		return core.compareTo(anotherString);
	}

	public int compareToIgnoreCase(String str) {
		return core.compareToIgnoreCase(str);
	}

	public boolean regionMatches(int toffset, String other, int ooffset, int len) {
		return core.regionMatches(toffset, other, ooffset, len);
	}

	public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) {
		return core.regionMatches(ignoreCase, toffset, other, ooffset, len);
	}

	public boolean startsWith(String prefix, int toffset) {
		return core.startsWith(prefix, toffset);
	}

	public boolean startsWith(String prefix) {
		return core.startsWith(prefix);
	}

	public boolean endsWith(String suffix) {
		return core.endsWith(suffix);
	}

	public int hashCode() {
		return core.hashCode();
	}

	public int indexOf(int ch) {
		return core.indexOf(ch);
	}

	public int indexOf(int ch, int fromIndex) {
		return core.indexOf(ch, fromIndex);
	}

	public int lastIndexOf(int ch) {
		return core.lastIndexOf(ch);
	}

	public int lastIndexOf(int ch, int fromIndex) {
		return core.lastIndexOf(ch, fromIndex);
	}

	public int indexOf(String str) {
		return core.indexOf(str);
	}

	public int indexOf(String str, int fromIndex) {
		return core.indexOf(str, fromIndex);
	}

	public int lastIndexOf(String str) {
		return core.lastIndexOf(str);
	}

	public int lastIndexOf(String str, int fromIndex) {
		return core.lastIndexOf(str, fromIndex);
	}

	public String substring(int beginIndex) {
		return core.substring(beginIndex);
	}

	public String substring(int beginIndex, int endIndex) {
		return core.substring(beginIndex, endIndex);
	}

	public CharSequence subSequence(int beginIndex, int endIndex) {
		return core.subSequence(beginIndex, endIndex);
	}

	public String concat(String str) {
		return core.concat(str);
	}

	public String replace(char oldChar, char newChar) {
		return core.replace(oldChar, newChar);
	}

	public boolean matches(String regex) {
		return core.matches(regex);
	}

	public boolean contains(CharSequence s) {
		return core.contains(s);
	}

	public String replaceFirst(String regex, String replacement) {
		return core.replaceFirst(regex, replacement);
	}

	public String replaceAll(String regex, String replacement) {
		return core.replaceAll(regex, replacement);
	}

	public String replace(CharSequence target, CharSequence replacement) {
		return core.replace(target, replacement);
	}

	public String[] split(String regex, int limit) {
		return core.split(regex, limit);
	}

	public String[] split(String regex) {
		return core.split(regex);
	}

	public String toLowerCase(Locale locale) {
		return core.toLowerCase(locale);
	}

	public String toLowerCase() {
		return core.toLowerCase();
	}

	public String toUpperCase(Locale locale) {
		return core.toUpperCase(locale);
	}

	public String toUpperCase() {
		return core.toUpperCase();
	}

	public String trim() {
		return core.trim();
	}

	public String toString() {
		return core.toString();
	}

	public char[] toCharArray() {
		return core.toCharArray();
	}

	public String intern() {
		return core.intern();
	}
}

JavaのStringクラスのこんなところがダメ

ほかにも、個人的に思うこと

シングルクォートでくくれない。JavaScript?を使うとそう思う。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-09-04 (水) 07:45:02 (3880d)