問題タブ [jls]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Javaキャスティング:コンパイラが間違っているのか、言語仕様が間違っているのか、それとも私が間違っているのか?
私はJava言語仕様、第3版を読んでいて、仕様とjavacコンパイラの実装との間の不一致であると私が思うものを見つけました。同じ不一致がEclipseコンパイラーにも存在します。
セクション15.16では、キャスト式について説明しています。引数タイプをキャスト変換(セクション5.5)でキャストタイプに変換できない場合は、コンパイル時エラーになるはずです。
オペランドのコンパイル時型が、キャスト変換の規則(§5.5)に従ってキャスト演算子によって指定された型にキャストされない場合は、コンパイル時エラーになります。それ以外の場合、実行時に、オペランド値は、キャスト演算子によって指定されたタイプに変換をキャストすることによって(必要に応じて)変換されます。
セクション5.5では、キャスト変換について説明します。許可されている変換タイプのリストが表示されます。特にリストに含まれていないのは、「開開変換とそれに続く拡大/縮小プリミティブ変換」です。ただし、その正確な変換シーケンスは、javacコンパイラー(およびEclipseコンパイラー)によって許可されているようです。例えば:
...正常にコンパイルされます。(問題のあるキャストはへのキャストlong
です。引数はタイプであるため、変換にはボックス化を解除してから、プリミティブ変換を拡張java.lang.Integer
する必要があります)。int
byte
同様に、JLSによると、からへのキャストは不可能です。これは、( 5.1.4char
によると)プリミティブ変換の拡大とプリミティブ変換の縮小が必要なためです。ただし、このキャストはコンパイラーによっても許可されます。
誰かが私を啓発できますか?
編集:これを求めて以来、私はOracleにバグレポートを提出しました。彼らの反応は、これが「JLSのグリッチ」であるというものです。
java - Java 言語仕様の第 4 版はいつ公開されますか?
JDK 7 開発者向けプレビューが公開されたので、新しい JLS の時期だと考える人もいるかもしれません。結局のところ、小さなものではありますが、言語に変更がありました。
私はまだ何も見つけていません。新しい JLS はいつ利用可能になり、どこから入手できますか?
eclipse - それは日食またはmaven-compiler-pluginのバグ、ジェネリッククラスのキャストの問題ですか?
私はこのようなコードを持っています:
TestCaseクラスで使用します。
このコードはEclipseで警告を出します:
クラスはrawタイプです。ジェネリック型クラスへの参照はパラメーター化する必要があります
と
この行の複数のマーカー
-タイプセーフティ:タイプMyClassの汎用メソッドdoSomething(String、Class)のチェックされていない呼び出しdoSomething(String、Class)
-タイプセーフティ:タイプクラスの式は、クラスに準拠するためにチェックされていない変換が必要です
このコード(テスト)をEclipseで実行すると、すべてが完全に機能します。コマンドプロンプトから「mvncleaninstall」を実行すると、次のようになります。
C:\ pathToProject \ src \ test \ java \ packagesPath \ MyTestCase.java:[xx、xxx]互換性のないタイプが見つかりました:
java.lang.Object
が必要です:com.somePackagePath.MyClass
しかし、提供する場合:
エラーや警告は表示されません。。Javaコンパイラが型情報を消去
することを理解しているので、Eclipseは警告の代わりにコンパイラエラーを提供するべきではありませんか、それとも問題を引き起こすのはmaven-plugin-compilerですか?
Mavenプラグインは次のとおりです。
よろしく、
デスポット
java - JVM は、特定のクラスをロードするときに、使用されているすべてのクラスをロードしますか?
JVM がクラス A をロードするとき、A 内で使用されるすべてのクラスをロードしますか?
そして、インポート宣言が何らかの形でロードプロセスに問題があるのではないかと思っていますか?
JLSへのリンクをいただければ幸いです。
java - Java: 変数アリティに適用されるコンパイル時の解決と「最も具体的な方法」
誰かが JLS re: most specific method のセクション 15.12.2.5 を理解するのを手伝ってくれませんか?
(JLSからの殴打されたカット&ペーストが続きます)
さらに、次のいずれかの場合、m という名前の可変アリティ メンバー メソッドは、同じ名前の別の可変アリティ メンバー メソッドよりも具体的です。
- 1 つのメンバー メソッドには n 個のパラメーターがあり、もう 1 つのメンバー メソッドには k 個のパラメーターがあります。ここで、n >= k です。最初のメンバ メソッドのパラメータの型は、T1、. . . 、Tn-1、Tn[]、他のメソッドのパラメータの型はU1、.. . 、英国-1、英国[]。2 番目のメソッドがジェネリックの場合、R1 ... Rp p1 をその正式な型パラメーターとし、Bl を Rl の宣言された境界、1lp とし、A1 ... Ap を推論される実際の型引数 (§15.12.2.7) とします。初期制約の下でのこの呼び出しに対して、Ti << Ui,1ik-1, Ti << Uk, kin and let Si = Ui[R1 = A1, ..., Rp = Ap] 1ik; それ以外の場合は、Si = Ui、1ik とします。次に: 1 から k-1 までのすべての j について、Tj <: Sj、および k から n までのすべての j について、Tj <: Sk、および、 2 番目の方法が上記の一般的な方法である場合、Al <: Bl [R1 = A1, ..., Rp = Ap], 1lp.
- 1 つのメンバー メソッドには k 個のパラメーターがあり、もう 1 つのメンバー メソッドには n 個のパラメーターがあります。ここで、n >= k です。最初のメソッドのパラメーターの型は、U1、. . . 、Uk-1、Uk[]、他のメソッドのパラメータの型はT1、.. 、Tn-1、Tn[]。2 番目のメソッドがジェネリックの場合、R1 ... Rp p1 をその正式な型パラメーターとし、Bl を Rl の宣言された境界、1lp とし、A1 ... Ap を推論される実際の型引数 (§15.12.2.7) とします。初期制約の下でのこの呼び出しに対して、Ui << Ti, 1ik-1, Uk << Ti, kin and let Si = Ti[R1 = A1, ..., Rp = Ap] 1in; それ以外の場合は、Si = Ti, 1in とします。次に: 1 から k-1 までのすべての j について、Uj <: Sj、および k から n までのすべての j について、Uk <: Sj、および 2 番目のメソッドが上記のようなジェネリック メソッドである場合、Al <: Bl [R1 = A1, ..., Rp = Ap], 1lp.
問題のジェネリックを無視すると、これは、あるメソッドが別のメソッドよりも具体的かどうかを判断するときに、可変引数がサブタイプよりも重要であるか、またはサブタイプが可変引数よりも重要であることを意味しますか? 私はそれを理解することはできません。
具体例: compute()
JLS によると、次のどの方法が「より具体的」ですか?
どちらが「より具体的」かわかりません。出力プリント
結果をどう解釈するか迷っています。最初の引数が文字列の場合、コンパイラはより具体的なサブタイプを持つメソッドを選択しました。最初の引数がオブジェクトの場合、コンパイラはオプションの可変引数の数が少ないメソッドを選択しました。
注: JLS のこのセクションを読んでおらず、引数の型に依存する回答をしている場合、あなたは私を助けていません。ジェネリックに関連する部分を除いて、JLS を注意深く読むと、「より具体的な」の定義は、実際の引数ではなく、宣言された引数に依存します。これは、JLS の他の部分で機能します (見つからない現時点では)。
たとえば、固定アリティ メソッドの場合compute(String s)
は、より具体的になりcompute(Object o)
ます。しかし、私は JLS re: variable arity メソッドの関連セクションを理解しようとしています。
java - Java: オーバーロードされたメソッドの解決と可変引数 -- 紛らわしい例
可変引数に適用されるJLS15.12を理解したと思ったとき、次の例を示します。
印刷する
私は最初の行を理解しています: JLS15.12は、メソッドの解決がフェーズで行われ、フェーズ 1 と 2 は可変引数メソッドを無視して互換性のあるメソッドがあるかどうかを調べ、フェーズ 3 (可変引数を含む) はフェーズ 1 と 2 が失敗した場合にのみ発生すると述べています。(JLSとこの SO の質問を参照してください。 ) したがって、該当compute(String s, Object... objects)
する場合は常に無視されcompute(Object obj1, Object obj2)
ます。
しかし、他の 2 行に 43 が表示される理由がわかりません。anObject[]
は an のインスタンスでもあるのにObject
、なぜ varargs メソッドと一致するのでしょうか?
編集:
...この
印刷し42
ます。
java - Java:コンパイル時の解決と「最も具体的な方法」
オーバーロードされた関数、、compute1()
を以下で使用しようとすると、コンパイルエラーが発生しますcompute2()
。compute5()
JLSセクション15.12を読んだ後、私は理解していると思います...オーバーロードされたメソッドのマッチングのフェーズ2(ボクシング/アンボクシングが許可され、varargsはありません)で、「最も具体的なメソッド」を決定するとき、JLSは(事実上)最も特定のメソッドは、正式なパラメーターが他の適用可能なメソッドのサブタイプであるメソッドであり、プリミティブとオブジェクト(egint
とInteger
)が互いにサブタイプになることはありません。したがってInteger
、はのサブタイプであり、はのサブタイプですが、とInteger
はw / r / tサブタイプの比較と互換性がないため、/ペアのどちらにも最も具体的な方法はありません。int
int
Integer
int
compute1()
compute2()
(incompute3()
と引数compute4()
を持つメソッドは、String
引数を持つメソッドよりも具体的であるObject
ため、プログラムは6と8を出力します。)
私の推論は正しいですか?
java - Javaジェネリック型のワイルドカードパラメータがその境界内にあるための正式な条件は何ですか?
Java のパラメーター化された型では、パラメーターがその境界内にあるかどうかをチェックするルールはどのようにワイルドカードに対して正確に機能しますか?
次のようなクラスがあるとします。
コンパイラが受け入れるものを試してみると、次のことがわかります。
- 無関係なインターフェイス タイプを使用した
? extends
ワイルドカードが許可されています:Foo<? extends Runnable>
は有効です ? extends
無関係なクラス タイプを使用するワイルドカードは許可されていません:はFoo<? extends Thread>
無効です。Number
型がとの両方のサブタイプになることはできないため、これは理にかなっています。Thread
- ワイルドカードでは、
? super
ワイルドカードの下限は型変数の境界のサブタイプである必要があります:はのサブタイプではないFoo<? super Runnable>
ため、許可されません。繰り返しますが、この制限は完全に理にかなっています。Runnable
Number
しかし、これらのルールはどこで定義されているのでしょうか? Java 言語仕様のセクション 4.5 を見ると、インターフェイスとクラスを区別するものは何もありません。JLSの私の解釈を適用すると、Foo<? super Runnable>
有効であると言われます。だから私はおそらく何かを誤解しました。これが私の試みです:
JLSのそのセクションから:
パラメーター化された型は、クラスまたはインターフェイス名 C と、実際の型引数リスト <T1 , ... , Tn> で構成されます。C がジェネリック クラスまたはインターフェイスの名前でない場合、または実際の型引数リスト内の型引数の数が C の宣言された型パラメーターの数と異なる場合、コンパイル時エラーになります。クラスまたはインターフェイス タイプの場合、明示的に除外されない限り、ジェネリック バージョンも含めます。このセクションでは、 A1 、 ... 、 An を C の仮型パラメーターとし、 Bi を Ai の宣言された境界とする。[Ai := Ti] という表記は、1 <= i <= n の場合、型変数 Ai を型 Ti に置き換えることを示し、この仕様全体で使用されます。
P = G<T1, ..., Tn> をパラメーター化された型とします。P がキャプチャ変換 (§5.1.10) の結果、型 G<X1, ..., Xn> になった後、実際の型引数 Xi, 1 <= i <= n ごとに、 Xi <: Bi[A1 := X1, ..., An := Xn] (§4.10)、またはコンパイル時エラーが発生します。
それを P = Foo<? super Runnable>
: に適用すると、C = Foo
、n = 1、T1 =? super Runnable
および B1 =が得られNumber
ます。
キャプチャ変換の場合、キャプチャ変換の定義のこの部分が適用されます。
Ti が ? 形式のワイルドカード型の引数の場合 super Bi の場合、Si は上限が Ui[A1 := S1, ..., An := Sn] で下限が Bi の新しい型変数です。
これにより、 G<X1, ..., Xn> =Foo<X>
が与えられます。ここX
で、 は上限Number
と下限を持つ新しい型変数ですRunnable
。そのような型変数を明示的に禁止しているものは見当たりません。
B1 = には型変数がないNumber
ため、 Bi[A1 := X1, ..., An := Xn] は単純に のままですNumber
。
X
はNumber
上限 (キャプチャ変換によるもの) であり、サブタイプ規則に従って、 「型変数の直接のスーパータイプは、その境界にリストされている型である」ため、X
<: Number
(= Bi[A1 := X1, ... , An := Xn]) であるため、このパラメーターはその境界内にあります。(しかし、そうではありません!)
同じ理由に従って、すべてのワイルドカードはその範囲内にあるため、ここで何かが正しくありません...しかし、この理由は正確にどこで間違っていたのでしょうか? これらのルールを正しく適用すると、どのように機能しますか?
java - JLSの構文の説明をどのように読む必要がありますか?
/blockquote>誰かがこの構文パターンを理解するのを手伝ってくれませんか?どういう意味ですか?
xx: " xxx
opt
"
java - JLS が Sun javac にどのように対応するか / それらが一致しない理由
これを与えられたJavaでは:
あなたは書ける
書き込みはできません (コンパイラ エラーが発生します)。
エラーは
現在、JLS Second Edition では、これは15.26.2 Compound Assignment Operatorsの次の行で説明できました。
All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.
しかし、JLS 第 3 版では、このコメントは消えました。複合演算子について述べられていることは、15.26.2 複合代入演算子だけです。
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
うまくいかないようです(上記を参照)。
だから私の質問は - javac と JLS の関係は正確には何ですか?この特定の例は javac のエラーですか、それとも JLS のエラーですか?