2

Недавно я наткнулся на запрос при чтении THE STRUCTURE OF THE JAVA VIRTUAL MACHINEГде скомпилированный код будет сохранен, если не в файле класса

На странице нет-5 гл. 2,

Составитель код, который будет выполняться в виртуальной машине Java является представлен с использованием формата Hard- и зависит от операционной системы бинарного , обычно (но не обязательно), которые хранятся в файле, известный как класса формат файла.

Этот кронштейн Но не обязательно является причиной.

Вопрос,

В этом случае скомпилированный код не будет сохранен в файле класса? и если он не будет сохранен в файле класса, то где и как?

Редактировать: Обратите внимание, что вопрос не о ClassLoader.

+1

Ну, вы можете сохранить его в байте [] в памяти или в базе данных, например. –

+0

@PeterLiljenberg, и это будет определено компилятором, правильно? –

+2

Компилятор java - это просто класс java, который вы можете вызвать так, да, выход будет определяться реализацией компилятора. Подробнее читайте в официальных документах: http://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html –

ответ

3

Вы, кажется, больше заинтересованы в том, чтобы создать класс Java файл в памяти, так что здесь идет:

public class CompileSourceInMemory { 
    public static void main(String args[]) throws IOException { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); 

     StringWriter writer = new StringWriter(); 
     PrintWriter out = new PrintWriter(writer); 
     out.println("public class HelloWorld {"); 
     out.println(" public static void main(String args[]) {"); 
     out.println(" System.out.println(\"This is in another java file\");");  
     out.println(" }"); 
     out.println("}"); 
     out.close(); 
     JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString()); 

     Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file); 
     CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits); 

     boolean success = task.call(); 

     if (success) { 
      try { 
       Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null }); 
      } catch (ClassNotFoundException e) { 
       System.err.println("Class not found: " + e); 
      } catch (NoSuchMethodException e) { 
       System.err.println("No such method: " + e); 
      } catch (IllegalAccessException e) { 
       System.err.println("Illegal access: " + e); 
      } catch (InvocationTargetException e) { 
       System.err.println("Invocation target: " + e); 
      } 
     } 
    } 
} 

class JavaSourceFromString extends SimpleJavaFileObject { 
    final String code; 

    JavaSourceFromString(String name, String code) { 
     super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),Kind.SOURCE); 
     this.code = code; 
    } 

    @Override 
    public CharSequence getCharContent(boolean ignoreEncodingErrors) { 
     return code; 
    } 
} 

Источник:In memory compilation

Это создает класс в памяти без какого-либо внешнего представления из java source или скомпилированный класс.

3

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

По умолчанию java URLClassLoader использует файлы в каталогах или баночках, так что откуда обычно происходит «типично», «необязательно» - это просто намек на то, что могут быть другие реализации.

+0

Что такое загрузка класса из скомпилированного кода, как насчет генерации скомпилированного кода? –

+0

Это просто специальный случай. Код будет сгенерирован/скомпилирован в памяти, а затем загружен загрузчиком классов ... – mata

2

Сохранение скомпилированного кода в файле .class является стандартным и более удобным способом получения исполняемого кода для JVM, однако один и тот же скомпилированный код может быть получен из многих других источников, его можно получить в виде текста или бинарный поток из БД или из сетевого соединения или из памяти во время выполнения, check this example или this one

+0

Это о получении сгенерированного скомпилированного кода, как насчет генерации скомпилированного кода? +1 для * Thats о загрузке класса из скомпилированного кода, как насчет генерации скомпилированного кода? * –

+1

Проверьте ссылки, и это тоже http://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler .html – Camilo

0

Да, этот вопрос касается Classloader!

Classloader - это (только) способ, которым JVM вводит классы. Классы могут быть в файлах, архивах JAR, где-то в сети, в блочном блоке базы данных в общей памяти на бумажной ленте (если у вашей машины есть устройство для чтения с бумажной лентой), или они могут даже генерироваться «на лету».

Итак, это ответ на ваш вопрос.

Стандартный компилятор использует для записи файлов классов, но, как прокомментировал Питер, это не обязательно так. И, прежде всего, только потому, что команда javac пишет файлы классов, что не означает, что мы должны использовать эти файлы. Обычно их упаковывают в JAR и используют вместо этого.