Пакет Java и вопрос о пути к классам - PullRequest
1 голос
/ 19 февраля 2010

Может кто-нибудь объяснить, пожалуйста, ответ на следующий вопрос:

Имеется правильно скомпилированный класс с исходным кодом:

 package com.sun.test;
 public class Commander {
  public static void main(String[] args) {
  }
 }

Предположим, что файл класса находится в / foo / com / sun / test /, текущим каталогом является / foo / и что путь к классам содержит "." (Текущий каталог). В какой командной строке правильно запускается Commander?

A. Java Commander

B. java com.sun.test.Commander

C. java com / sun / test / Commander

D. java -cp com.sun.test Commander

E. java -cp com / sun / test Commander

Ответы [ 3 ]

4 голосов
/ 19 февраля 2010

И лучшим ответом был бы B. C также работает на некоторых платформах, но не рекомендуется и очень редко (по крайней мере, я не видел его более 10 лет, программируя на Java).


EDIT

Распространенное заблуждение новичков в Java заключается в том, что имя класса является чем-то вроде «MyClass». Но это не точно; номенклатура «MyClass», как видно в объявлении class MyClass, действительно удобна для программиста, который компилятор комбинирует с объявлением пакета, чтобы создать то, что Java называет квалифицированным именем класса, которое все имена классов действительно относятся к среде выполнения. (В C # для этого они используют пространства имен).

Это становится вполне очевидным во многих случаях, таких как следы стека и сигнатуры методов, которые всегда содержат, например, java.lang.String. Потому что «String» - это просто краткая форма, которая разрешается в java.lang.String. Вы можете доказать это, создав собственную строку в своем собственном пакете ... но для этого нужно, чтобы вы явно использовали java.lang.String или my.package.String везде, где импортируются оба пакета или классы.

Как только вы усвоите тот факт, что все имена классов полностью определены, и что компилятор помогает вам избежать утомительной работы, используя импорт для преобразования коротких форм в полностью определенные формы, все становится понятнее.

Тогда должно быть очевидно, почему:

java -cp com / sun / test Commander

не работает. Опция cp помещает каталог ./com/sun/test (относительно текущего каталога) в путь к классу, но нет класса с именем Commander ... это com.sun.test.Commander. Это подразумевает две вещи: (a) командная строка требует com.sun.test.Commander и (b) classpath должен содержать запись для каталога, который содержит «com» ​​для разрешения этого класса, так как класс с именем xyMyClass должен быть в х / у относительно некоторого элемента classpath.


PS: Вы не должны использовать com.sun в качестве имени пакета, если только вы не работаете в Sun, поскольку доменное имя sun.com принадлежит Sun. Это соглашение существует, чтобы избежать упаковки классов и конфликтов имен.


PPS: существует такая вещь, как пакет по умолчанию, который «указывается» путем пропуска объявления пакета - но его почти никогда не следует использовать. Единственное законное место, которое я нашел, - это автономный «Launcher / Classloader», где желательно сделать:

java -cp . Launcher com.xxx.yyy.TargetApp

с Launcher.class в текущем каталоге ... и это только потому, что файлы JAR удерживаются заблокированными, пока приложение работает, а файлы классов нет, что означает, что Launcher.class может самообновляться, в то время как Launcher.jar не могу.

2 голосов
/ 19 февраля 2010

Если переменная среды CLASSPATH не задана (и, следовательно, текущий рабочий каталог по умолчанию находится в пути к классам), ответы следующие:

A.Не работает, в стандартном пакете нет класса Commander

B.Этот работает

C.Этот тоже работает, но B предпочтительнее

D.Путь к классу - foo / com.sun.test, где нет класса Commander в пакете по умолчанию

E.Путь к классу foo / com / sun / test, где в стандартном пакете нет класса Commander

2 голосов
/ 19 февраля 2010

A. Не работает, так как Java не найдет Commander класс

B. Будет работать, так как Java не найдет com.sun.test.Commander класс

C. Будет работать, по крайней мере, на платформе Windows. Вот почему вы должны использовать . вместо /.

D и E. Они не будут работать, потому что мы все еще просим Java искать класс Commander, а не com.sun.test.Commander

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