- PR -

オブジェクトについて

投稿者投稿内容
roushi
常連さん
会議室デビュー日: 2003/07/18
投稿数: 28
投稿日時: 2003-08-11 15:36
Javaについて勉強していますが
どうしてもひっかかる点があります。

Objクラスを他のクラスから利用したいと考えています。

------------------------------ @Start ------------------------------
public class Obj{
String[] str = {"正確","不正確"};
}
------------------------------- @End -------------------------------

@だと、コンパイルは正常に通りました。
宣言と代入を同時に行っていればOKなのでしょうか。

------------------------------ AStart ------------------------------
public class Obj{
String[] str = new String[2];

//このようなコンストラクタを作った場合もコンパイルは通りました。
public Obj(){
str[0] = new String();
str[0] = "正確";
}
}

------------------------------- AEnd -------------------------------

Aだと、他クラスでオブジェクトを作成する時にコンストラクタが
実行されるので、OKなのでしょうか。

------------------------------ BStart ------------------------------
public class Obj{
String[] str = new String[2];

//strの初期化を行うメソッド
public void set(){
str[0] = new String("正確");
}
}
------------------------------- BEnd -------------------------------

Bだと、他クラスでオブジェクトを作った後に、
オブジェクト変数.setメソッドで初期化を行うのでOKなのでしょうか。

@ABならまだ納得できますが、次の例は納得できません。

------------------------------ CStart ------------------------------

public class Obj{
String[] str = new String[2];
str[0] = new String("正確");
}
------------------------------- CEnd -------------------------------

しかしCだとエラーになってしまいます。
Cの場合だとObjクラスのインスタンスを作成していないのに
Objクラス内で、Stringオブジェクトを作成しようと
しているので、エラーが出てしまったのでしょうか。

エラー内容は以下の通りです。
C:\\gomi>javac gomi.java
gomi.java:26: ']' がありません。
str[0] = new String("正確");
^
gomi.java:26: <identifier> がありません。
str[0] = new String("正確");
^
gomi.java:26: シンボルを解釈処理できません。
シンボル: クラス str
位置 : Gomi の クラス
str[0] = new String("正確");
^
エラー 3 個

わかる方がいらっしゃれば、ご教授お願いします。
roushi
常連さん
会議室デビュー日: 2003/07/18
投稿数: 28
投稿日時: 2003-08-11 15:38
自己レスです

コンパイルの
javac gomi.javaとありますが

ただしくは
javac Obj.javaです。

よろしくお願いします。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-08-11 16:02
unibon です。こんにちわ。

#丸付き数字は機種依存文字なので使わないようにご留意ください。

別の掲示板ですが、たまたま同じ話題がありました。
http://www.vc-net.ne.jp/~ytp/bbs/java/bbs15281.html
のスレッドです。

いろいろやりかたはありますが、好みとしては初期化ブロック
(正確には「オブジェクト初期化子(Object Initializer)」と言うのでしょうか?)
を使うのが良いような気がします。
http://www.y-adagio.com/public/standards/tr_javalang/1_1Update.htm#12269



#以下、あとで追加しました(2003-08-12 13:08 頃)。

"Object Initializer" ではなく "Instance Initializer" でした。
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#246032


[ メッセージ編集済み 編集者: unibon 編集日時 2003-08-12 13:08 ]
roushi
常連さん
会議室デビュー日: 2003/07/18
投稿数: 28
投稿日時: 2003-08-11 17:54
返信ありがとうございます。
つまり、書き方自体がおかしくて
コンストラクタもしくはメソッドの中で
操作を行えば問題なくコンパイルが通るということですね。

public class Obj{
String[] str = {"正確","不正確"};
}
これは、オブジェクトを作成していないのかな・・・。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2003-08-11 17:59
引用:

javamanさんの書き込み (2003-08-11 17:54) より:
返信ありがとうございます。
つまり、書き方自体がおかしくて
コンストラクタもしくはメソッドの中で
操作を行えば問題なくコンパイルが通るということですね。

public class Obj{
String[] str = {"正確","不正確"};
}
これは、オブジェクトを作成していないのかな・・・。




オブジェクトを生成していますね。

ただ、unibonさんのリンクを見るとVMは
上記コードを以下のように認識するみたいですね。

コード:
public class Obj{ 
  String[] str;

  public Obj(){
    str = {"正確","不正確"};
  } 
} 

roushi
常連さん
会議室デビュー日: 2003/07/18
投稿数: 28
投稿日時: 2003-08-11 21:16
(株)ぽちさん
返信ありがとうございます。

VMによって解釈の違いがあるんですね
まだまだ勉強不足です・・・。

ぽちさんのおっしゃっていることは、ばっちりわかりました。
ありがとうございました。

お犬様
ベテラン
会議室デビュー日: 2003/01/26
投稿数: 67
投稿日時: 2003-08-11 22:38
引用:
javamanさんの書き込み (2003-08-11 15:36) より:

----------- (1)Start --------------
public class Obj{
String[] str = {"正確","不正確"};
}
------------ (1)End ---------------

(1)だと、コンパイルは正常に通りました。
宣言と代入を同時に行っていればOKなのでしょうか。

Java言語仕様でフィールド宣言は以下のように定義されています。
FieldDeclaration:
    FieldModifiersopt Type VariableDeclarators ;

VariableDeclarators:
    VariableDeclarator
    VariableDeclarators , VariableDeclarator

VariableDeclarator:
    VariableDeclaratorId
    VariableDeclaratorId = VariableInitializer

VariableDeclaratorId:
    Identifier
    VariableDeclaratorId [ ]

VariableInitializer:
    Expression
    ArrayInitializer

String[] str = {"正確","不正確"}; の構文は
Type VariableDeclarators ;
Type VariableDeclaratorId = VariableInitializer ;
Type VariableDeclaratorId = ArrayInitializer ;
と解釈できるので FieldDeclaration として適法です。

引用:
javamanさんの書き込み (2003-08-11 15:36) より:

(1)(2)(3)ならまだ納得できますが、次の例は納得できません。

----------- (4)Start --------------

public class Obj{
String[] str = new String[2];
str[0] = new String("正確");
}
----------- (4)Start --------------

しかし(4)だとエラーになってしまいます。(4)の場合だとObjクラスのインスタンスを作成していないのにObjクラス内で、Stringオブジェクトを作成しようとしているので、エラーが出てしまったのでしょうか。

Java言語仕様でクラス本体及びメンバ宣言は以下のように定義されています。
ClassBody:
    { ClassBodyDeclarationsopt }

ClassBodyDeclarations:
    ClassBodyDeclaration
    ClassBodyDeclarations ClassBodyDeclaration

ClassBodyDeclaration:
    ClassMemberDeclaration
    InstanceInitializer
    StaticInitializer
    ConstructorDeclaration

ClassMemberDeclaration:
    FieldDeclaration
    MethodDeclaration
    ClassDeclaration
    InterfaceDeclaration
    ;

String[] str = new String[2]; の構文は Type VariableDeclaratorId = VariableInitializer ; と解釈できるので適法です。str[0] = new String("正確"); は式文としては解釈できるのですが、クラス本体及びメンバ宣言をすべき箇所に書かれているため、InstanceInitializer StaticInitializer ConstructorDeclaration FieldDeclaration MethodDeclaration ClassDeclaration InterfaceDeclaration ; の何れかに該当しなければなりません。しかしながら、何れにも該当しないためコンパイラがエラーを出します。

引用:
(株)ぽちさんの書き込み (2003-08-11 17:59) より:

ただ、unibonさんのリンクを見るとVMは上記コードを以下のように認識するみたいですね。

そもそも仮想マシンはソースコードを認識しません。

引用:
javamanさんの書き込み (2003-08-11 21:16) より:

VMによって解釈の違いがあるんですね

今回の件に関しては仮想マシンは解釈しません。もっとも、ソースコードを直接解釈する仮想マシンを作ったのであれば話は別ですが、それは「Java仮想マシン」ではありません。

[ メッセージ編集済み 編集者: お犬様 編集日時 2003-08-11 23:00 ]
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2003-08-12 11:47
引用:

お犬様さんの書き込み (2003-08-11 22:38) より:

そもそも仮想マシンはソースコードを認識しません。




ごめんなさい。
VMではなくコンパイラですね。

スキルアップ/キャリアアップ(JOB@IT)