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

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

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

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

Q&A

解決済

2回答

4702閲覧

Java Calendar.getInstanceメソッドの戻り値

nom_0124

総合スコア23

Java

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

0グッド

0クリップ

投稿2017/07/15 12:08

編集2017/07/16 06:57

こんばんは。
Javaでよくわからない点があったので質問させてください。

今回はJava.utilパッケージのCalendarクラスについて勉強していた時に問題が生じました。
それはCalendar.getInstanceメソッドで返される値は何なのか?というものです。
以下はそのメソッドの定義です。

public static Calendar getInstance()

(厳密には何種類かありますが今回の話とは関係ないと思うので省略します)

この定義の戻り値の型にはCalendarクラス型が指定されています。
しかしCalendarクラスは以下のように抽象クラスとして定義されています。

public abstract class Calendar extends ...(省略)

つまり抽象クラスはインスタンス化出来ないので、getInstanceメソッドで返される値がCalenderインスタンスなのはあり得ないと思うのです。
だとしたら戻り値の候補は、Calendarクラスの子クラス?
でもgetInstanceメソッドのコードを確認したところ

public staticm Calendar getInstance(){ return createCalendar(TimeZone.getDefault(),Locale.getDefault(Locale.Category.FORMAT)); }

createCalendarメソッドは

private static Calendar createCalendar (TimeZone zone,Locale aLocale){ CalendarProvider provider=LocaleProviderAdapter.getAdapter(CalendarProvider.class,aLocale).getCalendarProvider(); if(provider != null){ try{ return provider.getInstance(zone,aLocale); }catch(IllegalArgumentException iae){ } } Calendar cal=null; if(aLocale.hasExtensions()){ String caltype=aLocale.getUnicodeLocaleType("ca"); if(caltype!=null){ switch(caltype){ case "buddhist": cal=new BuddhistCalender(zone,aLocale); break; case "japanese": cal=new JapaneseImperialCalendar(zone,aLocale); break; case "gregory": cal=new GregorianCalendar(zone,aLocale); break; } } } if(cal==nul){ if(aLocale.getLanguage()=="th"&&aLocale.getCountry()=="TH"){ cal=new BuddhistCalendar(zone,aLocale); }else if(aLocale.getVariant()=="JP"&&aLocale.getLanguage()=="ja"&&aLocale.getCountry()=="JP"){ cal=new JapaneseImperialCalendar(zone,aLoacale); }else{ cal=new GregorianCalendar(zone,aLocale); } } return cal; }

CalendarProviderクラスの定義は

public abstract class CalendarProvider extends LocaleServiceProvider

LocaleServiceProviderクラスの定義は

public abstract class LocaleServiceProvider

と継承元としてCalenderクラスが出てきません!
調べていくうちにこんがらがっちゃいました。
質問の内容は

  • Calender.getInstanceメソッドの戻り値の正体
  • 正体がCalendarインスタンスならどうして生成出来るのか?

以上二点をご説明頂ければ幸いです。

追記(7/16)

createCalendarメソッドの省略部分を展開しました。
実は昨日このメソッドを読んでる最中にパニックになってしまった上に、拒否反応を起こしてパソコンを閉じてしまったのです。
しかし悩みは解決したいという僕の都合の良いところ。
しっかりと把握すべきところに目を通さず、質問に走ってしまいました。
事実先程確認しましたところ、Calendarクラスが継承元であるクラスがnewされてる現場を目撃してしまいました。
今回の一件は僕の甘さと汚い性格が引き起こしたに他なりません。
皆様に多大なる迷惑をおかけしたこと心からお詫び申し上げます。

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

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

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

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

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

guest

回答2

0

以前はyonaさんの言う通りGregorianCalendarのインスタンスだったんですが、いつの間にか変わったんですね。

たとえば、Listはインタフェースのためそのままインスタンス化はできませんが、Listという型の変数を宣言することはできます。そしてListを実装したArrayListはインスタンス化でき、List型の変数に代入することができます。ArrayListに限らず、Listを実装したクラスのインスタンスであれば何でもList型の変数に入れることができます。

java

1List<String> list = new ArrayList<String>();

これと同じで、Calendarを返すというメソッドで、Calendarは抽象クラスのためCalendarのインスタンスは作れませんが、Calendarを継承したクラスのインスタンスであれば返すことができます。

CalendarProviderはCalendarを継承しているかというのは関係ありません。ポイントはそのメソッドgetInstance()がCalendar型のオブジェクトを返すことができるということです。
内部実装がどうなっているかはうかがい知れませんが、Calendar型のオブジェクトを返すことは保証されています。そのオブジェクトが実際どのようなクラスから生成されているかは読み取れませんし、その必要もあまりありません。

投稿2017/07/15 14:33

swordone

総合スコア20649

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

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

nom_0124

2017/07/15 23:05

>>GregorianCalendarのインスタンスだったんですが、いつの間にか変わったんですね。 このような情報はどこで入手出来るのでしょうか?
swordone

2017/07/15 23:41

あなたと同じように、以前このメソッドのコードを見ただけです。その際は return new GregorianCalendar(); だったという話です。
nom_0124

2017/07/16 07:07

回答そして返信ありがとうございます。 「無駄なことは気にしない」 この世界を生きていくための教訓を1つ学ばせていただきました。 何かと細かいところに固執してしまう僕にとっては今後の課題です。 本当に回答ありがとうございました。
guest

0

ベストアンサー

デフォルトはGregorianCalendarのインスタンスを返却します。ロケールによって返却されるインスタンスは変わりJapaneseImperialCalendarなども返却します。

また、戻り型がCalendarクラスなのはリスコフ置換原則というものに基づいているからです。
大雑把に言えば、サブクラスはスーパークラスと同様の役割を果たせるので、スーパークラスの参照型変数に入れて使用することができるという原則です。

投稿2017/07/15 12:21

yona

総合スコア18155

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

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

nom_0124

2017/07/16 07:03

単純明快かつ分かりやすい回答ありがとうございました。 リスコフ置換原則という言葉は初耳です。 為になりました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問