2009-04-24 4 views
12

Quelque chose qui m'a confondu - un exemple:Pourquoi l'importation de la classe pas nécessaire lorsque la méthode appelant exemple (Java)

Thing.java:

import java.util.Date; 

class Thing { 
    static Date getDate() {return new Date();} 
} 

(même paquet) TestUsesThing.java:

// not importing Date here. 

public class TestUsesThing { 

    public static void main(String[] args) { 
     System.out.println(Thing.getDate().getTime()); // okay 
     // Date date = new Date(); // naturally this wouldn't be okay 
    } 

} 

Pourquoi n'est-il pas nécessaire d'importer Date pour pouvoir appeler getTime() sur l'un d'eux?

+1

Ne pas vous dire 'System.out.println (Thing.getDate() getTime().);' – JeeBee

+0

@JeeBee: Cela fonctionnera comme écrit, mais vous avez raison de dire que c'est trompeur (toutes les choses auront la même date). –

+0

Oups, merci - ont corrigé. getDate() a démarré comme une méthode d'instance et j'ai oublié de changer l'appel pendant que j'écrivais. Leçon de gérer soi-même les choses après javac avant de poster. – jjujuma

Répondre

24

Importation en Java est uniquement nécessaire pour le compilateur sait quel est Date si vous tapez

Date date = new Date(); 

L'importation n'est pas comme #include en C/C++; tous les types sur le chemin de classe sont disponibles, mais vous import juste pour ne pas avoir à écrire le nom complet. Et dans ce cas, c'est inutile.

+0

Aha qui a un sens complet, merci! – jjujuma

+0

+1: J'apprends Java moi-même et de tout le matériel que j'ai lu, je ne me souviens pas avoir vu cette friandise d'information expliquée de cette façon. Cela éclaircit beaucoup. Merci. –

+0

L'autre commentaire un peu lié est que tout le paquet java.lang est importé automatiquement. Cela signifie que vous pouvez utiliser des choses comme System sans une instruction d'importation. –

1

Bonne question !!

Je pense que le résultat est la différence entre la manière dont le compilateur java gère les expressions et les instructions.

Date d = new Date(); // a statement 

où comme

new Thing().getDate().getTime() 

est une expression telle qu'elle se produit à l'intérieur appel de méthode println. Lorsque vous appelez getDate sur new Thing(), le compilateur essaie de gérer l'expression en examinant les informations de type de la classe Thing, où il obtient la déclaration de type Date. Mais lorsque vous essayez d'utiliser la date séparément dans une déclaration comme

Date d = new Thing().getDate(); 

vous assignez le résultat à un type dans le périmètre actuel (classe TestUsesThing), le compilateur essaie de résoudre le type dans ce champ d'application. Par conséquent, vous voyez l'erreur de compilation pour le type inconnu.

0

Est-ce que Thing et TestUsesThing sont dans le même paquet? Si c'est le cas, vous n'avez pas besoin d'importer Thing. La raison pour laquelle vous devez importer Date est parce que c'est dans un paquet différent.

+0

Oui, désolé, la question portait en effet sur l'import de la date, pas la relation entre les classes que j'ai clarifiées maintenant. – jjujuma

0

import Les instructions sont utilisées pour deux choses.

  1. Vérification du type de compilateur et éviter les conflits de nommage.
  2. lien Garantit code octet

Chaque fois que nous disons

System.out.println(new Thing().getDate().getTime()) 

Le compilateur parse cette déclaration gauche à droite et pénètre dans cette classe.

Analyse de premier niveau du compilateur.

  1. Aller à la classe chose
  2. compilation n'a pas de lien ou d'une erreur de ClassVersion de chose.classe

  3. Vérifiez Thing.class a méthode getDate.
  4. si # 3 est bon compilateur alors pointeur est toujours en Thing.class (qui a la date des déclarations d'importation) et je pourrais invoquer la méthode temps.
  5. En tant que consommateur, TestUsesThing obtient seulement une variable longue.

    System.out.println(new Thing().getDate()) 
    

    5,1 Dans ce cas, nous sommes implicitement accédons .toString() méthode

0

En fait, ce fut un exemple idéal, car il y a deux différentes classes Date Java standard: java.util .Date et java. sql .Date.

Comment sait-il que l'on à utiliser? Simple. La méthode getDate() est déclarée dans le cadre de la définition de la classe chose, et une partie de cette déclaration est son returntype:

public java.util.Date getDate() { 
    return this.date; 
} 

Bien sûr, si vous avez une importation dans la définition de la classe chose - et ce n'est pas ambigu, vous dites simplement:

public Date getDate() { 

Si vous deviez décoder le binaire de la classe chose, vous verriez la signature de la méthode de la méthode getDate et comprend le nom de classe entièrement qualifiés (y compris paquet) du type de retour.

Un import est simplement une manière de dire au compilateur quel (s) paquet (s) vous voulez supposer lorsque vous faites référence à des classes sans qualifications explicites. La liste des importations sera analysée chaque fois qu'un nom de classe non qualifié est vu, et les paquets seront recherchés. S'il n'y a pas d'ambiguïté (comme l'importation de java.util.date et de java.sql.Date), cette classe sera utilisée. Si vous pouvez déterminer la classe implicitement ou si le nom de la classe est entièrement qualifié, vous n'avez pas besoin d'importer.

Questions connexes