2016-04-13 13 views
0

私は最近Javaを学び、次の結論に達しました。 静的なネストされた型を宣言することは無意味な冗長性です。私はまた、インナータイプについて、その単語が静的締結 Can a Static Nested Class be Instantiated Multiple Times? - 私は、以下の質問に答えを読んで、私は答えを理解してください(アスカーが持っていたものと類似し、それは私のinetialの混乱をクリア)しばらくしてJava静的ネストされた型セマンティック

たとえば、内部型を静的として宣言しなかった場合は、内部型の新しいオブジェクトを作成できるように外部型をインスタンス化する必要はありません。結局そのネストされた型であり、外部型のメンバ/変数ではありません。私はちょうどいくつかのコード(静的削除)をテストし、私の前提は正しかった。

紛失したことはありますか?ここ

は、私がテストしたコード(私はIGameInput内部にKeyEventタイプから静的を削除したときにすべてのものがうまく働いた、注意してください)

package FrameWork; 
import java.util.List; 
public interface IGameInput { 

    //type definitions 
    public static class KeyEvent { 
public static final int KEY_DOWN = 0; 
public static final int KEY_UP = 1; 
public int type; 
public int keyCode; 
public char keyChar; 
    } 
} 

ある//////////////// ///////

package FrameWork.Imp; 


import java.util.ArrayList; 
import java.util.List; 

/* 
*/ 
public class Pool<T> 
{ 
    public interface PoolObjectFactory<T> { 
    public T createObject(); 
} 

    private final ArrayList<T> freeObjects; 
    private final PoolObjectFactory<T> factory; 
    private final int maxSize; 

    public Pool(PoolObjectFactory<T> factory, int maxSize) 
    { 
     this.factory = factory; 
     this.maxSize = maxSize; 
     this.freeObjects = new ArrayList<T>(maxSize); 
    } 

    public T newObject() 
    { 
     T object = null; 
     if (freeObjects.size() == 0) 
     { 
      object = factory.createObject(); 
     } 
     else 
     { 
      object = freeObjects.remove(freeObjects.size() - 1); 
     } 
     return object; 
    } 

    public void free(T object) 
    { 
     if (freeObjects.size() < maxSize) 
     { 
      freeObjects.add(object); 
     } 
    } 
} 

////////////////////////

package FrameWork.Imp; 

import java.util.ArrayList; 
import java.util.List; 
import android.view.View; 
import android.view.View.OnKeyListener; 
import FrameWork.IGameInput.KeyEvent; 
import FrameWork.Imp.Pool.PoolObjectFactory; 

public class KeyboardHandler implements OnKeyListener { 
    boolean[] pressedKeys = new boolean[128]; 
    Pool<KeyEvent> keyEventPool; 
    List<KeyEvent> keyEventsBuffer = new ArrayList<KeyEvent>(); 
    List<KeyEvent> keyEvents = new ArrayList<KeyEvent>(); 

    public KeyboardHandler(View view) { 

    PoolObjectFactory<KeyEvent> factory; 
    factory = 
     new PoolObjectFactory<KeyEvent>() { 
      @Override 
      public KeyEvent createObject() { 
      return new KeyEvent(); 
      } 
     }; 
    keyEventPool = new Pool<KeyEvent>(factory, 100); 
    view.setOnKeyListener(this); 
    view.setFocusableInTouchMode(true); 
    view.requestFocus(); 
    } 

    @Override 
    public boolean onKey(View v, int keyCode, android.view.KeyEvent event) { 
    if (event.getAction() == android.view.KeyEvent.ACTION_MULTIPLE) return false; 
    synchronized (this) { 
     KeyEvent keyEvent = keyEventPool.newObject(); 
     keyEvent.keyCode = keyCode; 
     keyEvent.keyChar = (char) event.getUnicodeChar(); 
     if (event.getAction() == android.view.KeyEvent.ACTION_DOWN) { 
     keyEvent.type = KeyEvent.KEY_DOWN; 
     if (keyCode > 0 && keyCode < 127) pressedKeys[keyCode] = true; 
     } 
     if (event.getAction() == android.view.KeyEvent.ACTION_UP) { 
     keyEvent.type = KeyEvent.KEY_UP; 
     if (keyCode > 0 && keyCode < 127) pressedKeys[keyCode] = false; 
     } 
     keyEventsBuffer.add(keyEvent); 
    } 
    return false; 
    } 
} 
+3

_私の前提は正しくありましたあなたは間違ったことをしているに違いありません。囲むインスタンスなしで内部型( 'static'なしでネスト)をインスタンス化することはできません。 – Savior

+2

インスタンス内からインスタンス化していないことは確かですか? – shmosel

+5

*私が見逃したことはありますか?*:はい:コードとその結論に至った経緯の説明。 –

答えて

3

あなた缶」 tは、非静的ネストされたクラスを含むクラスのインスタンスなしでインスタンス化します。あなたが含まれているクラスのインスタンス内でそれをインスタンス化する場合は、これを行うことができるだろう

class Test { 
    public static void main(String[] args) { //static, non-instance method 
     Inner inner = new Inner(); //error 
    } 

    class Inner { } 
} 

唯一の方法です(最も可能性が高いあなたの説明に基づいて、をやっている):

class Test { 
    public void someMethod() { //non-static, instance method 
     Inner inner = new Inner(); 
    } 

    class Inner { } 
} 
そうしないとあなたはコンパイル時にエラーが発生します

class Test { 
    public static void main(String[] args) { //static, non-instance method 
     Test test = new Test(); 
     Inner inner = test.new Inner(); //error 
    } 

    class Inner { } 
} 

:内部クラスをインスタンス化するために含むクラスのインスタンスを使用して

ORで :あなたのコード例では

non-static variable this cannot be referenced from a static context


、それは多くの意味があります。 KeyEventは依然として静的です。 JLS §9.5に探している相手:

A member type declaration in an interface is implicitly static and public.

これは、明示的に、またはstaticないとしてそれらを定義staticになるかどうか、すべてのクラスを意味します。

1

KeyEventは、インターフェイスIGameInputのネストされたクラスです。

インターフェイスのネストされたクラスは、常に暗黙的に静的(パブリック)です。

the JLSを参照してください:

A member type declaration in an interface is implicitly public and static. It is permitted to redundantly specify either or both of these modifiers.

だから、あなたの結論は正しいですが、インターフェイスのみのネストされたクラスのために。ネストされたクラスのクラスではfalseです。

+0

ありがとうございます、しばらくの間インターフェイスについて忘れることができます、それはGameInputInstance.KeyEventのようなものを持つ必要がある非静的なKeyEvenをインスタンス化するために、GameInputと呼ばれるクラスであったと仮定することができますke1 = new GameInputInstance.KeyEvent() ;今はKeyEventが静的で、次の文があります。GameInput.KeyEvent ke2 = new GameInput.KeyEvent; ke1とke​​2の違いはなんですか?どちらの場合も、内部型のインスタンスを作成しましたが、両方とも外部型のインスタンスに属していませんでした。 –

+0

私はGameInputのインスタンスに属していないと言います.GameInputにはKeyEventの参照/メンバーがありません。KeyEventの内部型定義を持っています。 –

+0

どうしたらコードをコンパイルしてみますか?実際にコンパイルした実際のコードを含む最小限の例で質問してください。 –

1

Java documentationに従う静的ネストされたクラスは、外部クラスをインスタンス化することなくインスタンス化することができます。注意:「実際には、静的なネストされたクラスは、動作上、パッケージの利便性のために別のトップレベルクラスにネストされたトップレベルのクラスです。」私たちは、このようなインナーとアウトクラスがある場合:

 A.B b1 = new A.B(); 
     A.B b2 = new A.B(); 

・ホープ、このことができます:

public class A { 
    static public class B { 
    } 
} 

を私たちは、このようなBの複数のインスタンスをインスタンス化することができます。

関連する問題