2016-04-08 8 views
1

Zum Beispiel in diesem einfachen Java-Programm:Warum kann ich bei der Verkettung eine Import-Anweisung weglassen, aber nicht, wenn ich sie einzeln anrufe?

  1. Wenn ich schreibe:

frame.getContentPane().add(button);

Ich brauche nur zu import javax.swing.*; und der Code kompiliert perfekt.

  1. Allerdings, wenn ich schreibe:

Container cont = frame.getContentPane(); cont.add(button);

ich beide haben import javax.swing.*; und import java.awt.*; denn es gibt kein cannot find symbol Compiler-Fehler zu sein.

Sind nicht beide Möglichkeiten, es technisch genau das Gleiche zu schreiben? Warum brauchen Sie weniger oder mehr Importanweisungen auf die eine oder andere Art?

Wenn ich es auf die erste Weise, wie in meinem Beispiel, aufrufen, gibt getContentPane() immer noch ein Container-Objekt zurück, obwohl ich es möglicherweise nicht mit einer Container-Referenzvariablen referenziere?

+0

'Container' ist eine Klasse aus dem' java.awt' Paket, vermutlich 'JFrame' ist eine Klasse aus' javax.swing' Paket, sie leben an verschiedenen Orten. * "Sind beide Wege, es technisch zu schreiben, genau gleich?" - Nein, das sind verschiedene APIs/Pakete/Namensräume – MadProgrammer

+0

Danke, aber es klärt es immer noch nicht für mich auf. Wenn ich es auf die erste Weise anrufe, wie in meinem Beispiel zu sehen ist, gibt 'getContentPane()' immer noch ein Objekt vom Typ "Container" zurück, obwohl ich es vielleicht nicht mit einer Referenzvariablen "Container" referenziere? –

+0

Ah sorry, das hat mehr damit zu tun, dass der '' JFrame' 'Container' importiert wurde, damit Java es finden kann, aber wenn du Java deklarierst, will ich wissen, welchen 'Container' du meinst, damit es sicher geht die Zuordnung ist richtig/gültig – MadProgrammer

Antwort

2

Vom Java:

Eine Einfuhranmeldung erlaubt ein benannte Typ oder ein statisches Element, um zu durch einen einfachen Namen bezeichnet wird (§ 6.2), die aus einer einzigen Kennung besteht.

Ohne die Verwendung einer entsprechenden Einfuhranmeldung, den einzigen Weg zu einem in einem anderen Paket deklarierte Typen beziehen, oder ein statisches Element von einem anderen Typ ist ein vollständig qualifizierter Name (§6.7) zu verwenden.

Also der einzige Grund, warum Sie die import benötigen, ist, so dass Sie den "gekürzten" Klassennamen verwenden können. Folgendes sollte ohne import java.awt.* mit arbeiten:

java.awt.Container cont = frame.getContentPane(); 
cont.add(button); 

Die „Chaining“ -Version des Codes implizit die qualifizierten Klassennamen verwendet, so gibt es keine Notwendigkeit für eine import -Anweisung.

+0

Vielen Dank! Definitiv hilft mir, einen Sinn daraus zu machen. –

1

Sie eine Variable vom Typ java.awt.Container

+0

Danke, aber es klärt es immer noch nicht für mich auf. Wenn ich es auf die erste Weise anrufe, wie in meinem Beispiel zu sehen ist, gibt 'getContentPane()' immer noch ein Objekt vom Typ "Container" zurück, obwohl ich es vielleicht nicht mit einer Referenzvariablen "Container" referenziere? –

+0

Der Import ist nur notwendig, um 'Container' anstelle von' java.awt.Container' schreiben zu können. Wenn Sie FQCN verwenden, ist kein Import erforderlich. – Vampire

0

Da die Container Klasse definiert, ist in diesem package:java.awt.*, dann IDE Sie beschwert sich fragen, wie gut diese Dateien zu importieren. Language Specification

+0

Danke, aber es klärt es immer noch nicht für mich auf. Wenn ich es auf die erste Weise anrufe, wie in meinem Beispiel zu sehen ist, gibt 'getContentPane()' immer noch ein Objekt vom Typ "Container" zurück, obwohl ich es vielleicht nicht mit einer Referenzvariablen "Container" referenziere? –

1

Der Grund ist, weil Java import ist ein wenig anders als in anderen Sprachen.

In Java sind während der Laufzeit alle Klassen im Klassenpfad für die JVM vorhanden.

Die Importanweisungen werden tatsächlich bereitgestellt, um dem Compiler zu helfen, zu identifizieren, welche Class Sie in dem Fall verwenden, wenn viele Klassen mit demselben Name vorhanden sind.

Also, warum sind sie nicht erforderlich, wenn Methodenverkettung?

Da der Compiler leicht wissen kann, welcher Typ von der bestimmten Methode zurückgegeben wird, kann es nie eine Mehrdeutigkeit geben.

+0

Das macht es klar! Ich habe nur C gelernt und lerne Java jetzt, gut zu wissen über die Import-Aussage und wie es sich von unterscheidet. Vielen Dank! –

0

Wenn wir schreiben:

frame.getContentPane().add(button); 

getContentPane() gibt ein anonymes Container-Objekt zur Laufzeit, wodurch die add (Button) Methode aufgerufen wird. Wenn Sie geschehen, JFrame Klasse zu überprüfen, wird es wie folgt aussehen:

import java.awt.Container; 
public class JFrame extends SomeClassName { 
    public Container getContentPane() { 
     Container cont; 
     //Some great code which assigns container with its appropriate value. 
     return cont; 
    } 
} 

Während, wenn wir schreiben:

Container cont = frame.getContentPane(); 
cont.add(button); 

Wir sind ein bekanntes Objekt zu erzeugen, dh es uns, für die Benennung der Compiler muss wissen, in Zu welchem ​​Paket gehört die Klasse Container.