GOF本のデザインパターンのCompositeパターンのJava版を実際に動かしてみようと思って、ちょっと手を加えて下記のようなコードにしているのですが、Mainのcabinet.add(chassis);の所で、
CompositeEquipmentクラスの_equipment.addElement(equipment);を呼び出した所で、
何故かNullPointerException例外が発生してしまいます。Equipmentクラス変数としてchassisのオブジェクトがequipmentに渡っているはずなのですが、理由がよく分かりません。どなたか、お分かりになる方、御教示いただけたらと思います。
//ここから
import java.util.Vector;
import java.util.Enumeration;
//Mainクラス
public class Main {
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
Cabinet cabinet = new Cabinet("PC Cabinet");
Chassis chassis = new Chassis("PC Chassis");
cabinet.add(chassis);
//以下省略
}
}
// Equipmentクラス
abstract class Equipment {
public Equipment(String name) {
_name = name;
}
String name() { return _name; }
//一部省略
public void add(Equipment equipment) { }
public void remove(Equipment equipment) { }
public Enumeration createEnumeration() {
return new NullEnumeration();
}
private String _name;
}
//CompositeEquipmentクラス
class CompositeEquipment extends Equipment {
public CompositeEquipment(String name) {
super(name);
// ...
}
//一部省略
public void add(Equipment equipment) {
_equipment.addElement(equipment);
//System.out.println(equipment);
}
public void remove(Equipment equipment) {
_equipment.removeElement(equipment);
}
public Enumeration createEnumeration() {
// concrete iterator を作成する
return new NullEnumeration();
}
private Vector _equipment;
}
//Cabinetクラス
ublic class Cabinet extends CompositeEquipment {
public Cabinet(String name) {
super(name);
// ...
}
// ...
}
//Chassisクラス
public class Chassis extends CompositeEquipment {
public Chassis(String name) {
super(name);
// ...
}
// ...
}
//ここまで
No.1ベストアンサー
- 回答日時:
return new NullEnumeration();
で、NullEnumerationクラスが未定義となっています。
また直接的な関係はありませんが、
Bruce Eckel, "Thinking in Java (4th Edition)" (Prentice Hall, 2006)
に、
「Vectorの使用は避けよ」
とあります。
http://oshiete.goo.ne.jp/qa/5918977.html
import java.util.*;
public class PersonalComputer {
public static void main(String[] args) {
Cabinet cabinet = new Cabinet("PC Cabinet");
Chassis chassis = new Chassis("PC Chassis");
cabinet.add(chassis);
cabinet.remove(chassis);
//以下省略
}
}
// Equipmentクラス
abstract class Equipment {
private String name;
protected Equipment(String name) {
this.name = name;
}
public String getName() {
return name;
}
//一部省略
abstract public void add(Equipment equipment);
abstract public void remove(Equipment equipment);
abstract public Iterator<Equipment> createIterator();
}
//CompositeEquipmentクラス
class CompositeEquipment extends Equipment {
private List<Equipment> equipments = new ArrayList<Equipment>();
protected CompositeEquipment(String name) {
super(name);
// ...
}
//一部省略
public void add(Equipment equipment) {
equipments.add(equipment);
System.out.println(equipment);
}
public void remove(Equipment equipment) {
equipments.remove(equipment);
}
public Iterator<Equipment> createIterator() {
// concrete iterator を作成する
return equipments.iterator();
}
}
//Chassisクラス
class Chassis extends CompositeEquipment {
public Chassis(String name) {
super(name);
// ...
}
// ...
}
//Cabinetクラス
class Cabinet extends CompositeEquipment {
public Cabinet(String name) {
super(name);
// ...
}
// ...
}
No.4
- 回答日時:
(補足1)
変数名は、Sun の Naming Convention に従うべきです。
http://www.oracle.com/technetwork/java/codeconve …
Variables
Variable names should not start with underscore _ or dollar sign $ characters, even though both are allowed.
(補足2)
Vector の使用は、「JVM 1.1 以前の環境を使っている時だけ」に限定すべきです。
http://www.velocityreviews.com/forums/t132806-ar …
John Bollinger:
Choose ArrayList unless you need the code to run in a 1.1 JVM. Period.
All of Vector's methods are synchronized and thus Vector might seem to
be a natural choice for multithreaded scenarios, but that is a trap.
There are a number of fairly routine usage scenarios that require
higher-level synchronization (e.g. iterating through the list), and
programmers who make a blanket assumption that Vector is safe for
multithreaded scenarios run into trouble. If you need to share a List
of some flavor among multiple threads then you must always analyze the
usage and synchronize appropriately. As long as you're going to do that
anyway, Vector doesn't really offer any advantage. You may also be able
to use fewer total monitors for synchronization (e.g. if there are other
shared objects you need to protect as well) with an ArrayList than with
a Vector. Plus, the explicit synchronization that you put in the source
code to protect an ArrayList clues in future maintainers to be thread-aware.
Dale King:
Multithreading is not a valid reason to use Vector since you can do:
List myList = java.util.Collections.synchronizedList(new ArrayList());
Supporting legacy is really the only reason to choose Vector.
Tony Morris:
A java.util.Vector should (speaking from a purist point of view) only be
used if you wish to support VMs prior to 1.2.
The same can be said for java.util.Hashtable.
If you need thread-safety you synchronize your java.util.List using
java.util.Collections.
This is the *nice* way of doing it.
There is no advantage to doing:
java.util.List l = new java.util.Vector();
over
java.util.List
No.3
- 回答日時:
考え方が逆ですね。
NullPointerExceptionはNullのオブジェクトを参照(メソッドの実行やフィールドへのアクセス)しようとした場合に発生します。
なので、このときに引数の equipment ではなく、まずは _equipment に着目するべきです。
解決方法はNo.2さんのおっしゃるとおり _equipment をインスタンス化すればいいです。
また、No.1さんのおっしゃるとおりに、なにか特別な事情がないのであればVectorではなくListを使った方がいいと思います。
おっしゃる通りです。
Java.utilのコレクション・フレームワークがまだ十分に使いこなせていないのが原因です。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# インターフェイスの実装
-
範囲外の数値を代入したらエラ...
-
クラス間でのデータ参照
-
関数内の変数に<summary>コメン...
-
visual studioのデザイナ画面で...
-
構造 他のクラスの構造体を別...
-
C++でfriendクラスにしているの...
-
C# log4netの使い方
-
無名パッケージからのインポート
-
デフォルトコンストラクタについて
-
Java リフレクションについて
-
super.paint(g)を呼び出す意...
-
ASP Pageの孫継承のPage_Load
-
C#にて別クラスの関数を使いたい
-
C++ シングルトン マルチスレッド
-
ひとつのファイルにクラスは1つ?
-
c++,ある関数のクラスから別の...
-
3種類の連想配列(java)
-
Java
-
ClassLoader.getSystemResource...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数内の変数に<summary>コメン...
-
クラス間でのデータ参照
-
C#にて別クラスの関数を使いたい
-
import と extends について
-
c++,ある関数のクラスから別の...
-
C++でfriendクラスにしているの...
-
Java リフレクションについて
-
構造 他のクラスの構造体を別...
-
C#のクラスライブラリでメッセ...
-
無名パッケージからのインポート
-
親クラスから子クラスへアクセス。
-
Java
-
C# インターフェイスの実装
-
Tomcatのpropertiesファイルの...
-
C# log4netの使い方
-
ひとつのファイルにクラスは1つ?
-
dllエクスポート時のdeclspec(d...
-
a href="..." とServlet
-
実行可能jarファイルのファイル...
-
C#でほかのファイルにある自作...
おすすめ情報