質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

4521閲覧

【java】コンストラクタ内のthis()内にフィールドを指定することは可能でしょうか?

newyee

総合スコア213

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/05/30 07:47

編集2018/05/30 08:34

javaを勉強中なのですが、分からないことがあります。
仮に以下のようなコードがあるとします。

java

1import java.util.*; 2 3public class Cleric1 { 4 5 String name; 6 7 int hp = 50; 8 9 static final int MAX_HP = 50; 10 11 int mp = 5; 12 13 static final int MAX_MP = 10; 14 15 16 public Cleric1(String name, int x, int y ) { 17 18 this.name = name; 19 20 this.hp = x; 21 22 this.mp = y; 23 } 24 25 public Cleric1(String name, int x) { 26 27 this(name,x,Cleric1.MAX_MP); 28 29 } 30}

上記のコードは、引数が2つのコンストラクタ内において、静的フィールドのMAX_MPを使用していますが、これが仮に通常のフィールド、「mp」などであった場合は、this()の中に引数として使用することはできますでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

newyee

2018/05/30 08:34

すみません。修正しました
KSwordOfHaste

2018/05/30 08:38

所謂XY問題というんでしょうか・・・。質問者さんは本当にやりたいことがあり、それを実現するために「これはできるか?」と尋ねておられるような気がします。本当にやりたいことを書いた方がより的確なアドバイスが付きやすくなると思います。
newyee

2018/05/30 08:46

ご指摘ありがとうございます。実は、javaの参考書でコンストラクタの勉強していたのですが、何故、静的フィールドは引数に使えるのに、通常のフィールドは使えないのかなと単純に疑問に思ったため、質問させて頂いたんですよね...
KSwordOfHaste

2018/05/30 08:48

おっと、そういうことだったのですね。そういうことならXY問題ではないですね。失礼しました。
guest

回答3

0

ベストアンサー

public Cleric1(String name, int x) { this(name,x,mp);

↑こういうことをやりたいの?

インスタンス変数mpはインスタンスの初期化が終わってないのでこういう使い方はできないですよ。

コメント返しの追記:

静的フィールドのMAX_MPが使用できるのに、何故通常のフィールドが使用できないのか

staticフィールドは、そのクラスがロードされた瞬間から使用可能になります。
だからjavaで処理を開始した時点で使用可能になっているわけです。

instanceフィールドはinstanceを生成して初めて使用可能になります。
単にjavaで処理を開始した時点で使用できないわけです。
処理の途中で明示的にinstannceを生成する必要があります。

たとえ話として居酒屋を例にしてみます。
staticなものは席に着いた(処理を開始した)らすぐに入手できるものです。
テーブルにセットされている箸などがこれに該当します。
instanceは、注文(生成)しないと入手できません。
焼き鳥や生ビールなどがこれに該当します。

さらに追記(コメント返し2):

3つの引数を定義している一つめのコンストラクタ内において

↑これは本来、

public Cleric1(String name, int x, int y ) { // super(); // ↑ソースコード内に記述されていないが、コンパイラとしては暗黙の了解で // サブクラスのコンストラクタ先頭でsuperクラスのデフォルトコンストラクタを呼ぶ // 土台となるinstanceが生成されるので、これ以降「this」を使って変数にアクセスできる this.name = name; this.hp = x; this.mp = y; }

↑こういう事です。
しかし、

public Cleric1(String name, int x) { this(name,x,Cleric1.MAX_MP); // ↑thisキーワードを使ってサブクラスのコンストラクタを呼ぶ場合、 // このコンストラクタ(Cleric1(String,int))先頭では「super()」が呼ばれない。 // 結果として、「this()」が完了するまでinstance変数にはアクセスできない。 }

↑こういう事になります。

投稿2018/05/30 08:20

編集2018/05/31 00:34
tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

newyee

2018/05/30 08:41

ご回答ありがとうございます。 勉強不足故申し訳ないのですが、インスタンス変数の初期化が終わっていないという点につきまして、もう少し教えて頂くことは可能でしょうか...? 自分としましては、静的フィールドのMAX_MPが使用できるのに、何故通常のフィールドが使用できないのかという点が分からないんですよね...
newyee

2018/05/30 22:07

ご丁寧にありがとうございます。 返信遅れてしまい、すみません。 自分も最初そのように思ったのですが、3つの引数を定義している一つめのコンストラクタ内において、「this.name」「this.hp」「this.mp」の3つのフィールドを使用しています...? そうだとするとやはり、どうしてthis()の中で使えないのかが分からないんですよね...
newyee

2018/05/31 07:15

ご丁寧にご説明くださりありがとうございます。 大変申し訳ないのですが、継承に関しましてはまだ勉強不足な為、勉強を進めていき、ご回答くださった内容がある程度理解できるようになった際に、ご返信、もしくはその上でご質問させて頂けたら幸いです...
newyee

2018/06/01 09:55

度々すみません。継承の勉強を進めてみたのですが、どうしても理解できない点があります... ご回答下さった内容で、サブクラスの先頭でsuperクラスのデフォルトコンストラクタを呼ぶ、という部分なのですが、super()が呼ばれるのは、クラスを継承している場合であって、継承していない場合は呼ばれないということではないでしょうか...? 今回ご質問に載せて頂いたコードはどのクラスも継承はしていないため、super()は呼ばれないのではないかと思ったもので...
swordone

2018/06/01 13:04

横から失礼。 どんなクラスもObjectは継承しているので、必ずObjectのコンストラクタは呼ばれることになります。
guest

0

staticフィールドは特別なフィールドです。

staticフィールドは各オブジェクト毎に用意されるものではなく、クラスで共通のものとして扱われます。つまり、オブジェクト生成に関係なく使用できます。(たとえオブジェクトの数が0でも使用できますし、オブジェクトの数が100個あったとしても、1つのstaticフィールドは1つしか用意されない)

一方、コンストラクタはオブジェクトを生成する途上のものであり、thisメソッドの引数に使用する段階における非staticフィールドは準備中みたいな状態のため使用できません。

何か最近static関係の回答ばかりしているような気がする・・・

投稿2018/05/30 13:13

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

JAVA

1 public Cleric1(String name, int x) { 2 3 this(name,x,this.MP); 4 }

できます

投稿2018/05/30 07:59

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

newyee

2018/05/30 08:25

ご回答ありがとうございます。 ご回答下さったように、やってみたのですが、以下のエラーが出てしまいました... C:\Users\Shinya\Desktop\java\Cleric1.java:27: エラー: スーパータイプのコンストラクタの呼出し前はthisを参照できません this(name, x , this.mp); ^ エラー1個
KSwordOfHaste

2018/05/30 08:36

tkturboさん回答が正しいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問