2016-04-13 16 views
0

Ich habe Java vor kurzem gelernt und kam zu der folgenden Schlussfolgerung: Deklaration eines statisch geschachtelten Typs ist eine sinnlose Redundanz.Java Static Verschachtelte Typ Semantic

ich die Antworten auf die Frage unten zu lesen und während ich die Antworten verstehe ich (und es gelöscht meine inetial Verwirrung - ähnlich dem der Fragesteller hatte) Can a Static Nested Class be Instantiated Multiple Times? ich auch zu dem Schluss, dass das Wort statisch in Bezug auf einen inneren Typ ist bedeutungslos, zum Beispiel, wenn wir den inneren Typ nicht als statisch deklariert haben, müssen wir den äußeren Typ nicht instanziieren, um neue Objekte des inneren Typs erstellen zu können. Nach all dem ist ein verschachtelter Typ und kein Mitglied/eine Variable vom äußeren Typ. Ich habe gerade einen Code getestet (statische entfernt) und meine Annahme war richtig.

Gibt es etwas, das ich vermisst habe?

hier ist der Code, den ich getestet (Hinweis, wenn ich Static von KeyEvent Typ innerhalb IGameInput entfernt, fein alles funktionierte)

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

_und meine Annahme war richtig_ Sie müssen etwas falsch gemacht haben. Sie können innere Typen (verschachtelt ohne 'statisch') ohne umschließende Instanz nicht instanziieren. – Savior

+2

Sind Sie sicher, dass Sie nicht aus einer Instanz instanziieren? – shmosel

+5

* Gibt es etwas, das ich vermisst habe? *: Ja: der Code und die Erklärung, wie Sie zu diesem Schluss gekommen sind. –

Antwort

3

Sie Dose‘ t Instanziieren Sie eine nicht statische geschachtelte Klasse ohne eine Instanz der enthaltenden Klasse.

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

    class Inner { } 
} 

Der einzige Weg, Sie seien in der Lage, dies zu tun ist, wenn Sie es innerhalb einer Instanz der enthaltenden Klasse instanziiert (am ehesten, was Sie tun, basierend auf Ihrer Erklärung):

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

    class Inner { } 
} 

Oder durch eine Instanz der Klasse enthält, mit der inneren Klasse zu instanziiert:

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

    class Inner { } 
} 

Andernfalls werden Sie die Fehler bei der Kompilierung erhalten :

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


mit Ihrem Code Beispiel macht es viel mehr Sinn. KeyEvent ist immer noch statisch. Ein Blick in JLS §9.5:

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

Diese alle Klassen bedeutet, ob Sie sie explizit als static definieren oder nicht, wird static sein.

1

KeyEvent ist eine verschachtelte Klasse der SchnittstelleIGameInput.

Verschachtelte Klassen einer Schnittstelle sind immer implizit statisch (und öffentlich).

Siehe 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.

Also, Ihre Schlussfolgerung ist richtig, aber nur für verschachtelte Klassen von Schnittstellen. Es ist falsch für verschachtelte Klassen von Klassen.

+0

Danke, Ok, vergiss die Schnittstellen für eine Weile, nehmen wir an, es war eine Klasse namens GameInput, jetzt um ein nicht statisches KeyEven instanziieren zu können brauche ich etwas wie GameInputInstance.KeyEvent ke1 = new GameInputInstance.KeyEvent() ; jetzt, wenn KeyEvent statisch war und ich die folgende Anweisung hatte GameInput.KeyEvent ke2 = new GameInput.KeyEvent; Was genau ist der Unterschied zwischen ke1 und ke2? In beiden Fällen habe ich eine Instanz des inneren Typs erstellt, die beide keiner Instanz des äußeren Typs angehören! –

+0

und ich sage, dass sie keiner Instanz von GameInput gehören, da GameInput keinen Verweis/Mitglied von KeyEvent hat, es nur eine innere Typdefinition von KeyEvent –

+0

Wie Sie das tun, versuchen Sie, Ihren Code zu kompilieren, zu sehen der Unterschied für sich selbst, und stellen Sie eine Frage mit einem minimalen Beispiel, das echten Code enthält, der tatsächlich kompiliert? –

1

Gemäß Java documentation Statisch verschachtelte Klassen können instanziiert werden, ohne die äußere Klasse instanziieren zu müssen. Hinweis: "Eine statische geschachtelte Klasse ist im Grunde genommen eine Klasse der obersten Ebene, die zum Zweck der Paketerstellung in eine andere Klasse der obersten Ebene geschachtelt wurde." Wenn wir innere und aus Klasse wie dieses:

public class A { 
    static public class B { 
    } 
} 

Wir können mehrere Instanzen von B wie folgt instanziiert:

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

Hoffnung, das hilft.