Почему импорт класса не требуется при вызове метода на экземпляре (Java) - PullRequest
12 голосов
/ 24 апреля 2009

Что-то, что меня смутило - пример:

Thing.java:

import java.util.Date; 

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

(тот же пакет) 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
    }

}

Почему нет необходимости импортировать Date, чтобы иметь возможность вызывать getTime () для одного из них?

Ответы [ 5 ]

25 голосов
/ 24 апреля 2009

Импорт в Java необходим только для того, чтобы компилятор знал, что такое Date, если вы наберете

Date date = new Date();

Импорт не похож на #include в C / C ++; все типы на пути к классам доступны , но вы import их просто избегаете необходимости писать полное имя. И в этом случае это не нужно.

1 голос
/ 24 апреля 2009

Хороший вопрос !!

Я думаю, что результатом является разница между тем, как java-компилятор обрабатывает выражения против операторов.

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

где как

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

- это выражение, которое встречается внутри вызова метода println. Когда вы вызываете getDate для нового Thing (), компилятор пытается обработать выражение, просматривая информацию о типе для класса Thing, где он получает объявление типа Date. Но когда вы пытаетесь использовать Date отдельно в выражении типа

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

вы присваиваете результат типу в текущей области (класс TestUsesThing), компилятор пытается разрешить тип в этой области. В результате вы видите ошибку компилятора для неизвестного типа.

0 голосов
/ 24 апреля 2009

На самом деле, это был идеальный пример, поскольку есть два различных стандартных класса Java Date: java.util.Date и java. sql .Date .

Откуда он знает, какой использовать? Просто. Метод getDate () объявлен как часть определения класса Thing, а частью этого объявления является его возвращаемый тип:

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

Конечно, если у вас есть импорт в определении класса Thing - и это не двусмысленно, вы просто говорите:

public Date getDate() {

Если бы вы декодировали двоичный файл класса Thing, вы бы увидели сигнатуру метода метода getDate, и она включает полное имя класса (включая пакет) возвращаемого типа.

import - это просто способ сообщить компилятору, какой пакет (ы) вы хотите использовать при обращении к классам без явных квалификаций. Список импорта будет проверяться всякий раз, когда будет замечено неквалифицированное имя класса, и пакеты будут искать. Если нет никакой двусмысленности (такой как импорт java.util.date и java.sql.Date), этот класс будет использоваться. Если вы можете определить класс неявным образом или если имя класса полностью определено, вам не нужно импортировать.

0 голосов
/ 24 апреля 2009

import операторы используются для нескольких вещей.

  1. Проверка типа компилятора и избежание конфликта имен.
  2. Обеспечивает связь с байтовым кодом

Всякий раз, когда мы говорим

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

Компилятор анализирует этот оператор слева направо и попадает в этот класс.

Разбор компилятора первого уровня.

  1. Перейти к классу вещей
  2. компиляция не имеет ошибок связывания или ClassVersion из Thing.class

  3. Проверьте, есть ли в Thing.class метод getDate.
  4. если # 3 хорошо, тогда указатель компилятора все еще находится в Thing.class (в котором есть операторы импорта даты), и я могу вызвать метод Time
  5. В качестве потребителя TestUsesThing получает только длинную переменную.

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

    5.1 В этом случае мы неявно обращаемся к методу .toString ()

0 голосов
/ 24 апреля 2009

Вещи и TestUsesThing в одном пакете? Если это так, то вам не нужно импортировать Thing. Причина, по которой вам нужно импортировать Date, заключается в том, что она находится в другой упаковке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...