Javaでプライベート静的ネストされたクラスのために合成アクセサを警告Eclipseの?
-
06-09-2019 - |
質問
私の同僚は、Eclipseコードの書式設定と警告設定のいくつかは、より厳格であることを行うことを提案しました。これらの変更の大半は意味をなさないが、私はJavaでこの1つの奇妙な警告が表示されます。ここで「問題」を再現するためにいくつかのテストコードは次のとおりです。
package com.example.bugs;
public class WeirdInnerClassJavaWarning {
private static class InnerClass
{
public void doSomething() {}
}
final private InnerClass anInstance;
{
this.anInstance = new InnerClass(); // !!!
this.anInstance.doSomething();
}
}
// using "this.anInstance" instead of "anInstance" prevents another warning,
// Unqualified access to the field WeirdInnerClassJavaWarning.anInstance
とライン!私は私の新しい警告の設定でEclipseでこの警告を与えます:
囲むコンストラクタにアクセス WeirdInnerClassJavaWarning.InnerClass() 合成アクセサによってエミュレートされます 方法。その可視性を増加します あなたのパフォーマンスを向上させます。
これは何を意味するのでしょうか?私は私には意味がありません「保護された静的クラス」に「プライベート静的クラス」を、変更したときに警告が表示されなくなります。
<時間>の編集の私は最終的に "正しい" 修正を考え出しました。ここでの本当の問題は、このネストされたプライベート静的クラスがpublicコンストラクタを欠落していることのようです。その1つの微調整は警告を削除:
package com.example.bugs;
public class WeirdInnerClassJavaWarning {
private static class InnerClass
{
public void doSomething() {}
public InnerClass() {}
}
final private InnerClass anInstance;
{
this.anInstance = new InnerClass();
this.anInstance.doSomething();
}
}
私はクラスがプライベート入れ子になったクラス(これは他のクラスは、囲むクラスのサブクラスを含む、それへのアクセスを持つことはできません)になりたいと私はそれが静的なクラスになりたい。
というよりも、プライベートで保護入れ子になったクラスを作る「問題」を固定する別の方法である、なぜ私はまだ理解していませんが、多分それは、Eclipseの癖/バグがあります。
(謝罪は、私はそれがより明確にするInnerClassの代わりにNestedClass呼ばれている必要があります。)
解決
あなたは警告を取り除くことができます:
package com.example.bugs;
public class WeirdInnerClassJavaWarning {
private static class InnerClass {
protected InnerClass() {} // This constructor makes the warning go away
public void doSomething() {}
}
final private InnerClass anInstance;
{
this.anInstance = new InnerClass();
this.anInstance.doSomething();
}
}
他の人が言ったように明示的なコンストラクタを持つプライベートクラスは、Javaコンパイラが作成した合成方法を介した以外、外部からインスタンス化することはできませんので、、Eclipseが不平を言っています。あなたのコードを取る場合は、それをコンパイルして、 JAD の(*)とそれを逆コンパイル、あなたが得る次(再フォーマット):
public class Test {
private static class InnerClass {
public void doSomething() {}
// DEFAULT CONSTRUCTOR GENERATED BY COMPILER:
private InnerClass() {}
// SYNTHETIC METHOD GENERATED BY THE JAVA COMPILER:
InnerClass(InnerClass innerclass) {
this();
}
}
public Test() {
anInstance.doSomething();
}
// Your instance initialization as modified by the compiler:
private final InnerClass anInstance = new InnerClass(null);
}
あなたが保護されたコンストラクタを追加する場合は、、合成コードは不要です。合成コードは、理論的にですが、私は、publicまたはprotectedコンストラクタを使用して非合成コードよりminescule量によって遅くなると仮定します。
(*)JADについては、私はWikipediaのページにリンクされている...このプログラムをホストドメインの有効期限が切れていますが、私は自分自身をテストしていない別のWikipediaのリンク。私は他の(おそらくより最近の)逆コンパイラがある知っているが、これは私が使用して開始したものです。注意:のとき、逆コンパイル、最近のJavaクラスファイルは、のは文句を言うが、それはまだ良い仕事をしていません。
。他のヒント
ところで、警告をオフにする設定は、「コードスタイル」の下でJavaのエラー/警告ページであると呼ばれます:
囲むタイプの非アクセス部材へのアクセス
あなたはWeirdInnerClassJavaWarningからInnerClassをインスタンス化することはできません。これは、JVMがあなたをすることはできないだろう、プライベートだが、(何らかの理由で)Java言語でしょう。
そのため、javacはそのためWeirdInnerClassJavaWarningからInnerClassインスタンスを作成することを許可する、)(ちょうど新しいInnerClassを返しますInnerClassで追加の方法になるだろう。
私はあなたが本当にもパフォーマンスの低下がinmeasureably小さなことになるので、それを取り除くために必要とは思いません。しかし、あなたはあなたが本当にしたいことができるかどうか。
というよりも、プライベートで保護入れ子になったクラスを作る「問題」を固定する別の方法である、なぜ私はまだ理解していませんが、多分それは、Eclipseの癖/バグがある
これは、Eclipseの癖/バグ、ジャワの機能だけではありません。 Java言語仕様、8.8.9 と言います:
クラスが保護宣言されている場合は、...、デフォルトのコンストラクタが暗黙的に保護されたアクセス修飾子を与えている...
ここでは、人々を助けるためにあなたが
との問題の元のクラスのコードを使用している場合、あなたが得るものですjavac -XD-printflat WeirdInnerClassJavaWarning.java -d tmp
生の出力は、コンパイラは、コメントを追加しました。合成パッケージプライベートクラスとコンストラクタの追加に注意します。
public class WeirdInnerClassJavaWarning {
{
}
public WeirdInnerClassJavaWarning() {
super();
}
{
}
private final WeirdInnerClassJavaWarning$InnerClass anInstance;
{
this.anInstance = new WeirdInnerClassJavaWarning$InnerClass(null);
this.anInstance.doSomething();
}
}
class WeirdInnerClassJavaWarning$InnerClass {
/*synthetic*/ WeirdInnerClassJavaWarning$InnerClass(WeirdInnerClassJavaWarning$1 x0) {
this();
}
private WeirdInnerClassJavaWarning$InnerClass() {
super();
}
public void doSomething() {
}
}
/*synthetic*/ class WeirdInnerClassJavaWarning$1 {
}
あなたが代わりにプライベートまたは保護された、すなわちデフォルトのスコープを使用してそれを取り除くことができる必要があります。
static class InnerClass ...
また、私は警告してコードの行にカーソルを置き、CTRL-1を押していることは注目に値します、Eclipseはあなたのために自動的にこの問題を解決できる可能性があります。