#java #jvm #javac
#java #jvm #javac
Вопрос:
Я только что узнал об этом, и я надеюсь, что у кого-то есть ключ к пониманию того, что происходит. Команды для выполнения (запустите это во временном каталоге, предварительно очистив все):
Никаких проблем:
cat << EOF > Myface.java
public interface Myface {}
EOF
cat << EOF > Myclass.java
public class Myclass implements Myface {}
EOF
javac Myface.java
javac Myclass.java
Myclass не будет компилироваться:
cat << EOF > Myface.java
package Mypackage;
public interface Myface {}
EOF
cat << EOF > Myclass.java
package Mypackage;
public class Myclass implements Myface {}
EOF
javac Myface.java
javac Myclass.java
Myclass НЕ БУДЕТ компилироваться:
cat << EOF > Myface.java
package Mypackage;
public interface Myface {}
EOF
cat << EOF > Myclass.java
package Mypackage;
public class Myclass implements Myface {}
EOF
javac Myclass.java
Что здесь происходит?
РЕДАКТИРОВАТЬ: все команды, выполнить:
javatest@l-bel-smai-ubuntu:~$ ls
javatest@l-bel-smai-ubuntu:~$ pwd
/home/javatest
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myface.java
> public interface Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myclass.java
> public class Myclass implements Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$
javatest@l-bel-smai-ubuntu:~$ javac Myface.java
javatest@l-bel-smai-ubuntu:~$ javac Myclass.java
javatest@l-bel-smai-ubuntu:~$ ls
Myclass.class Myclass.java Myface.class Myface.java
javatest@l-bel-smai-ubuntu:~$ rm *
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myface.java
> package Mypackage;
> public interface Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myclass.java
> package Mypackage;
> public class Myclass implements Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$
javatest@l-bel-smai-ubuntu:~$ javac Myface.java
javatest@l-bel-smai-ubuntu:~$ javac Myclass.java
Myclass.java:2: cannot find symbol
symbol: class Myface
public class Myclass implements Myface {}
^
1 error
javatest@l-bel-smai-ubuntu:~$ rm *
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myface.java
> package Mypackage;
> public interface Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$
javatest@l-bel-smai-ubuntu:~$ cat << EOF > Myclass.java
> package Mypackage;
> public class Myclass implements Myface {}
> EOF
javatest@l-bel-smai-ubuntu:~$
javatest@l-bel-smai-ubuntu:~$ javac Myclass.java
Myclass.java:2: cannot find symbol
symbol: class Myface
public class Myclass implements Myface {}
^
1 error
javatest@l-bel-smai-ubuntu:~$
Комментарии:
1. Можете ли вы показать команды, которые вы запускали, папки, из которых вы их запускали, и сообщения об ошибках, которые были выведены компилятором?
2. Файлы Java / Class должны быть помещены в путь к классу в структуре вложенных папок в соответствии с их пакетами. Возможно, в этом и заключается проблема.
3. Боже, какой длинный день. Ты прав, Гэндальф. Напишите это в ответе и получите свой приз ;).
4. В Java нет требования, чтобы исходные файлы находились в какой-либо конкретной структуре каталогов (некоторые инструменты могут зависеть от этого, но ни один из JDK не делает этого, о чем я знаю). Конечно, разумно поместить их в структуру каталогов 🙂
5. @TofuBeer Это просто не так. Структура файла JAR полностью определена, и ожидается, что «свободные» файлы .class, расположенные в файловой системе, будут соответствовать той же структуре каталогов. В противном случае поиск по пути к классу не будет работать, поэтому здесь не удается выполнить сбой.
Ответ №1:
Да, вот так: структура каталогов файлов Java / Class должна соответствовать структуре пакета, в которой объявлены классы Java, чтобы компиляция и загрузка классов работали правильно.
Ответ №2:
Во время компиляции Myclass.java добавьте параметр classpath (путь к классу)
javac -classpath . Myclass.java
Ответ №3:
Случай 2: при компиляции Myclass.java
javac
будет искать Mypackage/Myface.class
. Этого там нет. Вы должны скомпилировать с javac -d .
помощью which makes javac
, чтобы создать соответствующую структуру каталогов для классов, которые он генерирует. Это также неявно указано в пути поиска для следующего javac
вызова.
Случай 3: при компиляции Myclass.java
он будет искать Mypackage/Myface.class
, затем для подходящего исходного файла, указанного в командной строке, затем для подходящего Mypackage/Myface.java
исходного файла. Ни того, ни другого не существует. Либо скомпилируйте, javac -d Myface.java Myclass.java
либо вставьте *.java
в соответствующую структуру каталогов, указанную именами пакетов.