OpenJDKソース研究ノート(十五):JDKの中の10の論争に富んだ設計にツッコミを入れる
最初の14の文章は、JDKで学ぶべきコードと設計方法を共有しています.
コインごとに両面があります.Every coin has two sides.
もちろん、JDKにも改善や議論に値するデザインがたくさんあります.
本編では、JDKの中の10の議論に富んだデザインについて詳しく突っ込みます.
ネットユーザーは1.異常を求めて投げて、誤ったヒントは合理的ではありません.
OpenJDKソース研究ノート(一)-パラメータチェック&キーエラーメッセージ付きの異常を投げ出すこの記事で、あるネットユーザーは「3番目のifのヒント情報に問題がある.前の2つのifはpositionもsizeも負ではないことを説明している.和を求めるのは通常負ではない.一つだけは和を求めることがあふれているのではないか.このとき異常情報がこのように投げ出すと、かえって情報が明確ではない」と指摘している.
2.タグインタフェースは注釈で置き換えることができます.
OpenJDKソース研究ノート(三)-ReandomAccessなどのタグインタフェースの役割この文章では、あるネットユーザーが「空のインタフェース、例えばSerializableなどは、一つの記号にすぎず、実用的なannotationが適切だ」と指摘している.
例えばArrayListの定義はclass ArrayList implements Serialiable{}である.
@Serializeclass ArrayList{}のいくつかの観点に変更できます
a.注記はJDK 1.5ならではです.以前のAPIはもちろんサポートすべきだった.注釈なら、いいと思います.簡潔に見えないかもしれません.空のインタフェースを実現するにはinstanceofが便利です.
b.インタフェースを実現しても、注釈を使ってもいい.最終的には,いずれも1つの設計の2つの異なる実装である.実装インタフェースはInstance of,注釈呼び出しメソッドを用いる.インタフェースを使用すると、以前のコードとよりよく互換性があります.c.互換性の観点から見ると、確かにそうです.しかし、設計目的から見ると、注釈のほうがいいです.また、オブジェクト継承構造に影響を及ぼさず、タグを付けます.
メソッド定義3.定義方法を繰り返します.
親インタフェースCollectionを継承した以上、親にすでに存在するインタフェースを繰り返し定義するのはなぜですか?
public interface Setextends Collectionなどのインタフェースの定義も同様である.
4.両端キューの同じ動作には2つの類似の実装がある.
なぜ2つのAPIを定義するのですか?繰り返しているように見え、疑問を抱かれやすい.
5.集合インタフェースSetの戻り値が異なる.
なぜこの方法で値を返さなかったのですか?
public void add(int index, E element) ;
上記の3つの方法はいずれも戻り値があり,同様にadd(E e)でもboolean戻り値がある.
設計問題6.リストがサブリストを生成すると,元のリストを操作できなくなる.
以上のコードはjavaを投げ出す.util.ConcurrentModificationException
ある時、私たちは確かにこの需要を持っています.
JDKがこのように設計されている以上、私たちはできるだけ上記の使い方を避けるしかありません.
7.可変集合の実現方式. java.util.Collections.unmodifiableList(list);
この方法の実装は,実際には「可変」のリスト実装を返す.
それらのリストを修正する方法を,異常を投げ出すように実現する.
ソースコードを見る前に、私はいつも他の方法があるような気がします.
ソースコードがこのように実現されているのを見て、私は少しがっかりしました.
考えすぎたようだ.
8.パラメータチェックが不合理です.
単純にクラスを呼び出す方法ですgetClass();をクリックして、クラスがnullであるかどうかを確認します.
この方法はもっといいですか?
if(newFormatter==null){
throw new NullPointerException("");
}
コーディング習慣
9.If文のかっこの問題.ほとんどの文は1つのif文だけがこのように書かれています.
私は以下の書き方に慣れていて、「目がくらむ」ことを防ぎます. if (f == null){ throw new NoSuchElementException();}また、if(f==null)/異常を投げ出したり、印刷文throw new NoSuchElementException();この書き方は、見間違えやすい.このようなコードはたくさんありますが、if文がさらにネストされていると、見間違えやすくなります.
10.使用されない変数. java.util.logging.LogManagerには次の変数定義があります. private final static Handler[] emptyHandlers = {};上のコードは使用されていません.
Eclipseには警告がありますが、黄色の感嘆符はうるさいです.
関連読書
私のCSDNブログコラムOpenJDKソースコード研究ノート
OpenJDKソースコード研究中に整理した学習ノート.OpenJDKはGPLライセンス(GPL-licensed)のJavaプラットフォームのオープンソース実装である.
原文参照:http://FansUnion.cn/articles/3174(小雷網-FANSUnion.cn)
コインごとに両面があります.Every coin has two sides.
もちろん、JDKにも改善や議論に値するデザインがたくさんあります.
本編では、JDKの中の10の議論に富んだデザインについて詳しく突っ込みます.
ネットユーザーは1.異常を求めて投げて、誤ったヒントは合理的ではありません.
OpenJDKソース研究ノート(一)-パラメータチェック&キーエラーメッセージ付きの異常を投げ出すこの記事で、あるネットユーザーは「3番目のifのヒント情報に問題がある.前の2つのifはpositionもsizeも負ではないことを説明している.和を求めるのは通常負ではない.一つだけは和を求めることがあふれているのではないか.このとき異常情報がこのように投げ出すと、かえって情報が明確ではない」と指摘している.
protected FileLock(AsynchronousFileChannel channel, long position,
long size, boolean shared) {
if (position < 0)
throw new IllegalArgumentException("Negative position");
if (size < 0)
throw new IllegalArgumentException("Negative size");
if (position + size < 0)
throw new IllegalArgumentException("Negative position + size");
this.channel = channel;
this.position = position;
this.size = size;
this.shared = shared;
}
2.タグインタフェースは注釈で置き換えることができます.
OpenJDKソース研究ノート(三)-ReandomAccessなどのタグインタフェースの役割この文章では、あるネットユーザーが「空のインタフェース、例えばSerializableなどは、一つの記号にすぎず、実用的なannotationが適切だ」と指摘している.
例えばArrayListの定義はclass ArrayList implements Serialiable{}である.
@Serializeclass ArrayList{}のいくつかの観点に変更できます
a.注記はJDK 1.5ならではです.以前のAPIはもちろんサポートすべきだった.注釈なら、いいと思います.簡潔に見えないかもしれません.空のインタフェースを実現するにはinstanceofが便利です.
b.インタフェースを実現しても、注釈を使ってもいい.最終的には,いずれも1つの設計の2つの異なる実装である.実装インタフェースはInstance of,注釈呼び出しメソッドを用いる.インタフェースを使用すると、以前のコードとよりよく互換性があります.c.互換性の観点から見ると、確かにそうです.しかし、設計目的から見ると、注釈のほうがいいです.また、オブジェクト継承構造に影響を及ぼさず、タグを付けます.
メソッド定義3.定義方法を繰り返します.
public interface List<E> extends Collection<E>{
int size();
boolean isEmpty();
}
親インタフェースCollectionを継承した以上、親にすでに存在するインタフェースを繰り返し定義するのはなぜですか?
public interface Set
4.両端キューの同じ動作には2つの類似の実装がある.
java.util.Deque<E>
/**
* 1 。
* , null。
*/
E peekFirst();
/**
* 1 。
* peekFirst , , 。
* @throws NoSuchElementException if this deque is empty
*/
E getFirst();
なぜ2つのAPIを定義するのですか?繰り返しているように見え、疑問を抱かれやすい.
5.集合インタフェースSetの戻り値が異なる.
java.util.Set
public abstract E get(int index);
public E set(int index, E element);
public boolean add(E e);
なぜこの方法で値を返さなかったのですか?
public void add(int index, E element) ;
上記の3つの方法はいずれも戻り値があり,同様にadd(E e)でもboolean戻り値がある.
設計問題6.リストがサブリストを生成すると,元のリストを操作できなくなる.
List<E> subList(int fromIndex, int toIndex);
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
List<String> subList = list.subList(0,2);
subList.add("C");
以上のコードはjavaを投げ出す.util.ConcurrentModificationException
ある時、私たちは確かにこの需要を持っています.
JDKがこのように設計されている以上、私たちはできるだけ上記の使い方を避けるしかありません.
7.可変集合の実現方式. java.util.Collections.unmodifiableList(list);
この方法の実装は,実際には「可変」のリスト実装を返す.
static class UnmodifiableList<E> extends UnmodifiableCollection<E>
implements List<E> {
private static final long serialVersionUID = -283967356065247728L;
final List<? extends E> list;
UnmodifiableList(List<? extends E> list) {
super(list);
this.list = list;
}
public E get(int index) {
return list.get(index);
}
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
}
それらのリストを修正する方法を,異常を投げ出すように実現する.
ソースコードを見る前に、私はいつも他の方法があるような気がします.
ソースコードがこのように実現されているのを見て、私は少しがっかりしました.
考えすぎたようだ.
8.パラメータチェックが不合理です.
java.util.logging.Handler.setFormatter(Formatter)
public void setFormatter(Formatter newFormatter) throws SecurityException {
checkAccess();
// Check for a null pointer:
newFormatter.getClass();
formatter = newFormatter;
}
単純にクラスを呼び出す方法ですgetClass();をクリックして、クラスがnullであるかどうかを確認します.
この方法はもっといいですか?
if(newFormatter==null){
throw new NullPointerException("");
}
コーディング習慣
9.If文のかっこの問題.ほとんどの文は1つのif文だけがこのように書かれています.
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
私は以下の書き方に慣れていて、「目がくらむ」ことを防ぎます. if (f == null){ throw new NoSuchElementException();}また、if(f==null)/異常を投げ出したり、印刷文throw new NoSuchElementException();この書き方は、見間違えやすい.このようなコードはたくさんありますが、if文がさらにネストされていると、見間違えやすくなります.
public ScriptEngineManager() {
ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader();
if (canCallerAccessLoader(ctxtLoader)) {
if (DEBUG)
System.out.println("using " + ctxtLoader);
init(ctxtLoader);
} else {
if (DEBUG)
System.out.println("using bootstrap loader");
init(null);
}
}
10.使用されない変数. java.util.logging.LogManagerには次の変数定義があります. private final static Handler[] emptyHandlers = {};上のコードは使用されていません.
Eclipseには警告がありますが、黄色の感嘆符はうるさいです.
関連読書
私のCSDNブログコラムOpenJDKソースコード研究ノート
OpenJDKソースコード研究中に整理した学習ノート.OpenJDKはGPLライセンス(GPL-licensed)のJavaプラットフォームのオープンソース実装である.
原文参照:http://FansUnion.cn/articles/3174(小雷網-FANSUnion.cn)