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

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

新規登録して質問してみよう
ただいま回答率
85.35%
参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

Java

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

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

Q&A

解決済

2回答

881閲覧

メソッド参照でstaticメソッドを呼び出したい

oh.........

総合スコア1

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

Java

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

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

0グッド

0クリップ

投稿2020/06/27 02:54

編集2020/06/27 03:25

前提・実現したいこと

Java8から実装されたメソッド参照の勉強中です。

staticなメソッドを参照する際に、::の左側をインスタンスにするとコンパイルエラーが発生する理由がわかりません。

インスタンス.staticメソッドは呼び出しが可能なのに、なぜ
インスタンス::staticメソッドはコンパイルエラーが発生するのでしょうか。

発生している問題・エラーメッセージ

Main.java:10: error: incompatible types: invalid method reference list.forEach(new Sample()::print); //インスタンスでstaticメソッドを参照 ^ unexpected static method print(Integer) found in bound lookup Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error

該当のソースコード

import java.util.*; public class Main { public static void main(String[] args){ List<Integer> list = List.of(1,2,3); Sample.print(0); ////クラス指定でstaticメソッドを呼び出し list.forEach(Sample::print);//クラス指定でstaticメソッドを参照 教本通り    new Sample().print(0); //インスタンスからstaticなメソッド printを呼び出し list.forEach(new Sample()::print); //この記述方法でエラーが発生する } }

試したこと

上記のコードで挙動を確認した結果、コンパイルエラーが発生しました。

###補足
paiza.ioで実行しました。

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

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

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

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

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

swordone

2020/06/27 03:05

エラーメッセージを載せてください。
oh.........

2020/06/27 03:16

エラーメッセージ掲載しました。ご指摘ありがとうございます。
退会済みユーザー

退会済みユーザー

2020/06/27 03:17 編集

ソースコードとエラーメッセージは以下のように分けて挿入しましょう。 ### 該当のソースコード ```Java import java.util.*; public class Main { ... } ``` ### エラーメッセージ ``` Main.java:10: ... 1 error ```
oh.........

2020/06/27 03:26

編集しました。ご指摘ありがとうございます。
guest

回答2

0

ベストアンサー

純粋に文法に則ってないからですよね。

::によるメソッド参照は
https://docs.oracle.com/javase/specs/jls/se11/html/jls-19.html#jls-19-15
のMethodReferenceの部分がその文法規則ですが

new Sample()を左側に許すような文法がない

からエラーです。


インスタンス.staticメソッドは呼び出しが可能なのに

これは若干語弊があって、
式.staticメソッド(引数)
という呼び出しは可能ですが、この時どんなメソッドが呼び出されるかの決定にインスタンスは関係しません
.の左の式の型で静的に(=コンパイル時に)決まります。(だからstaticメソッドと呼ばれるのです)

java

1 public static void main(String[] args){ 2 Sample s = null; 3 s.print(0); 4 }

はprintがstaticメソッドなら正当に動くコードです。
s.print(0);では、"式sの型"がSampleで、printがSampleのstaticメソッドなので、静的に呼び出すメソッドが決まって、Sample.printを呼び出すようなバイトコードになります。

new Sample().print(0)がコンパイルを通るのは、"new Sample()という式の型"がSampleで、printがSampleのstaticメソッドなので、静的に呼び出すメソッドが決まるからです。結果Sample.printを呼び出すようなバイトコードになります。

投稿2020/06/27 05:59

編集2020/06/27 06:11
quickquip

総合スコア11235

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

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

oh.........

2020/06/27 06:36

リンク先の文法規則、確認しました。納得です。今後も文法に疑問を覚えたとき参考にします。 また、私の認識違いについても解説していただきありがとうございます。 インスタンス.staticメソッド(引数) で書かれた式はコンパイル時に クラス.staticメソッド(引数) と同じ挙動をする様に読み替えられているのですね。 わかりやすい説明ありがとうございました。ベストアンサーとさせていただきます。
guest

0

staticメソッドはインスタンスから呼び出すものではない、からです。
とりあえずはそう覚えておきましょう

投稿2020/06/27 03:25

y_waiwai

総合スコア88042

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

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

oh.........

2020/06/27 03:41

staticメソッドはインスタンスから呼び出すものではない、承知しました。回答ありがとうございます。 ソースコードに掲載した new Sample().print(0); のように、インスタンスからstaticなメソッドを呼び出す処理が特殊な例で、基本的にstaticメソッドはインスタンスから呼び出すものではない という認識で合っていますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問