Скомпилированные интерфейсы на Java

#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 в соответствующую структуру каталогов, указанную именами пакетов.