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

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

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

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

Q&A

解決済

4回答

2495閲覧

javaのCalendarクラスについて。

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

1グッド

0クリップ

投稿2016/08/03 13:35

java.util.Calendarクラスについてです。
APIを見ていると、わからなくなってしまいましたので、質問させてください。
例えば、

Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);

とすれば、変数yearには2016が格納されるわけですが、
Calendarクラスを見てみると

public final static int YEAR = 1;

とあります。
また、getメソッドを見てみると、
public int get(int field)
{
complete();
return internalGet(field);
}

completeメソッド及び、internalGetメソッドを見てみると、

protected void complete()
{
if (!isTimeSet)
updateTime();
if (!areFieldsSet || !areAllFieldsSet) {
computeFields(); // fills in unset fields
areAllFieldsSet = areFieldsSet = true;
}
}

protected final int internalGet(int field)
{
return fields[field];
}

となっております。
pudateTimeメソッドは

private void updateTime() {
computeTime();
// The areFieldsSet and areAllFieldsSet values are no longer
// controlled here (as of 1.5).
isTimeSet = true;
}

coputeTimeメソッドは抽象メソッドでした。
これらのコードからなぜyearに2016が代入されるのか理解できません。
一体どうなっているのでしょうか。
ご存知の方がいらっしゃれば、ぜひご教授願いたいです。

down_voter👍を押しています

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

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

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

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

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

guest

回答4

0

java Calendar のコンストラクタの実装

Calendar.YEAR は配列へアクセスするためのキーですよ

java

1/*946*/ protected Calendar(TimeZone zone, Locale aLocale) 2/*947*/ { 3/*948*/ fields = new int[FIELD_COUNT]; 4/*949*/ isSet = new boolean[FIELD_COUNT]; 5/*950*/ stamp = new int[FIELD_COUNT]; 6/*951*/ 7/*952*/ this.zone = zone; 8/*953*/ setWeekCountData(aLocale); 9/*954*/ }

投稿2016/08/03 15:51

asahina_dev

総合スコア610

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

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

0

ベストアンサー

###Calendar.YEAR
Calendarクラスのgetやsetメソッドの引数には"フィールド"を表す整数を入れる場所があります。"フィールド"とは、日付、時刻のある部分を指すものと考えるといいでしょう、YEARの場合は「年」のフィールド、つまり「このカレンダーが指す年」を、getメソッドでは取得し、setメソッドでは別の値に設定するわけです。
ここでCalendarクラスのstatic final変数YEARの値自体には意味はありません。年のフィールドを指定するための値を「1」に決めているというだけです。getメソッドで「1」という値を受け取った際には「年」を返すようにしている、ただそれだけです。

###computeTimeメソッドについて
setメソッドで値を設定しただけでは**Calendarオブジェクトの持っている各フィールドの値は更新されていません。**getしようとするときに各フィールドの値を再計算するのがcompleteメソッドということになります。おそらくfields[]に、配列の先頭から順に年月日時分秒などが格納されており、そのインデックスが先ほどの定数に対応しているのだと思われます。そして渡された定数に対応する配列の要素を返す、という設計になっているのだと思います。

ちなみにCalendar.getInstance()で返ってくるCalendarオブジェクトはGregorianCalendarというクラスのオブジェクトです。

投稿2016/08/03 15:46

swordone

総合スコア20651

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

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

0

Javaのソースが見れないので推測ですが。

①fieldsは配列か何かでこの中に年、月、日などの各種値を管理

②YEARは定数でfieldsの年の値を保持する要素へのインデクサ

③completeメソッドは時間計算をし値の呼び出し準備を完了する機能(fieldsに値をぶち込んでると思われる)

④completeメソッド内のisTimeSetがfalseの場合のみ、時間の計算がまだなのでupdateTimeメソッド呼び出し。

⑤computeTimeで派生クラスのカレンダーに基づくルールで時間を計算

⑥計算が終わったのでisTimeSetをtrueにしてupdateTimeの再呼び出しを防止

⑦areFieldsSetかareAllFieldsSetがfalse、つまり年月日などを管理する配列で値がセットされてない項目があるならcomputeFieldsメソッドで全てのフィールド値を算出

⑧算出後に⑦で判定したフラグをどちらもtrueに変更(computeFieldsの再呼び出し防止)

⑨internalGetメソッドで引数のインデクサに該当する要素から値を取り出し(掲示のソース部分だと年)

流れはざっとこんな感じかと。
英語を解読しただけというのは秘密(

###追記
長く書いてきましたが、
恐らく派生クラス(各種カレンダークラス)でオーバライドしている、
抽象メソッドのcomputeTimeが肝となっている予感です。

計算方法を詳しく知るには派生クラスのcomputeTimeメソッドの実装を見ることが出来れば分かるかもしれませんね。

投稿2016/08/03 14:01

編集2016/08/03 14:21
Panzer_vor

総合スコア1636

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

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

0

Calendar#getInstanceの中を見てください。
GregorianCalendarのインスタンスが返却されているはずです。
さらにGragorianCalendarのコンストラクタを見てください。現在時刻がセットされているはずです。

投稿2016/08/03 13:51

yona

総合スコア18155

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問