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で質問しましょう!
似たような質問が見つかりました
- Java java final 1 2022/06/10 22:49
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java javaのクラスの分け方について質問です。 APIの内部用と外部用でクラスを分けたいのですがインター 2 2022/04/26 16:06
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- Java 直し方について教えて頂きたいです。 4 2022/08/13 02:11
- Java リレーションエンティティクラスとは何ですか? 2 2023/02/10 00:02
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#でほかのファイルにある自作...
-
ひとつのファイルにクラスは1つ?
-
無名パッケージからのインポート
-
関数内の変数に<summary>コメン...
-
Publicとは?
-
super.paint(g)を呼び出す意...
-
C++でfriendクラスにしているの...
-
C#にて別クラスの関数を使いたい
-
エクセルVBAで、条件に一致する...
-
「天声人語」をインターネット...
-
ArrayListのgetメソッドが実行...
-
servletからjspへオブジェクト...
-
NTPサーバーへのアクセス
-
C#「オブジェクト参照が必要で...
-
execute()
-
LISTBOXの内容が更新されま...
-
packageとimport の違いって?
-
javaで、、、
-
命名規約は連番でいいのか?
-
JSPでclassのimport
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
クラス間でのデータ参照
-
範囲外の数値を代入したらエラ...
-
関数内の変数に<summary>コメン...
-
c++,ある関数のクラスから別の...
-
C#にて別クラスの関数を使いたい
-
java-別クラスの変数の使い方を...
-
C++でfriendクラスにしているの...
-
a href="..." とServlet
-
親クラスから子クラスへアクセス。
-
構造 他のクラスの構造体を別...
-
Java リフレクションについて
-
import と extends について
-
C#でほかのファイルにある自作...
-
C#のクラスライブラリでメッセ...
-
Java
-
アップキャスト、ダウンキャス...
-
無名パッケージからのインポート
-
違うクラスからの変数の共有化
-
SwingでgetContentPaneのエラー...
-
ひとつのファイルにクラスは1つ?
おすすめ情報