2

는 최근에 나는 쿼리를 가로 질러왔다. 2,

컴파일 된 코드는 자바 가상 머신에 의해 실행되는 것은 는 일반적으로 하드웨어 -과 운영 체제에 독립적 바이너리 형식을 사용하여 표현 (그러나 필요하지 않음) 클래스로 알려진 파일에 저장됩니다 파일 형식.

그 브래킷 그러나 반드시 일 필요는 없습니다. 컴파일 된 코드가 클래스 파일에 저장되지 않습니다

하는 경우 질문입니다

? 그리고 그것이 클래스 파일에 저장되지 않는다면, 어디서 어떻게됩니까?

편집 : 질문은 ClassLoader가 아닙니다.

+1

글쎄, 메모리 나 데이타베이스의 byte []로 유지할 수 있습니다. –

+0

@ PeterLiljenberg 이것은 컴파일러에 의해 정의됩니다. 맞습니까? –

+2

자바 컴파일러는 호출 할 수있는 자바 클래스이므로 예는 컴파일러 구현에 따라 결정됩니다. 공식 문서에서 자세한 내용을 읽어보십시오. http://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html –

답변

3

당신은 너무 여기에 메모리에 자바 클래스 파일을 생성하는 방법에 더 많은 관심을 보인다는 간다 :

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

자바 소스 또는 컴파일 된 클래스.

3

Java에서 클래스 로더가 컴파일 된 바이너리를 가져 오는 위치는 구현에 따라 다릅니다. 데이터베이스, 넷, 메모리 또는 다른 생각할 수있는 위치에서 클래스를로드하는 클래스 로더를 작성할 수 있습니다.

기본값 인 java URLClassLoader은 디렉토리 또는 jar 파일에있는 파일을 사용하므로 "일반적으로"가 나오는 곳에서 "반드시 필요하지는 않은"것은 다른 구현이있을 수 있다는 힌트 일뿐입니다.

+0

컴파일 된 코드에서 클래스를로드하는 방법에 대해 컴파일 된 코드를 생성하는 방법은 무엇입니까? –

+0

그건 단지 ahter 특별한 경우입니다. 코드가 생성/메모리에 컴파일 된 다음 클래스 로더에 의해로드 된 것입니다 ... – mata

2

.class 파일에 컴파일 된 코드를 저장하는 것은 JVM 용 실행 가능 코드를 가져 오는 표준 및보다 편리한 방법이지만 동일한 컴파일 된 코드를 다른 많은 소스에서 얻을 수 있으며 텍스트 또는 DB 또는 네트워크 연결 또는 런타임의 메모리로부터의 바이너리 스트림 check this example 또는 this one

+0

그게 컴파일 된 코드를 생성에 관한, 컴파일 된 코드를 생성하는 방법에 대해? +1 for * 컴파일 된 코드에서 클래스를로드하는 방법에 대해 컴파일 된 코드를 생성하는 방법은 무엇입니까? * –

+1

링크를 확인하십시오. http://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler .html – Camilo

0

네,이 질문은 Classloader에 관한 것입니다!

클래스 로더는 JVM에서 클래스를 가져 오는 유일한 방법입니다. 클래스는 파일, JAR 아카이브, 네트워크 어딘가에, 데이터베이스 blob, 공유 메모리, 페이퍼 테이프 (페이퍼 테이프 리더가있는 경우) 또는 즉시 생성 될 수 있습니다.

귀하의 질문에 대한 답변입니다.

표준 컴파일러는 클래스 파일을 작성하는 데 사용하지만 Peter가 주석으로 설명했듯이 반드시 그런 것은 아닙니다. 그리고 무엇보다 javac 명령이 클래스 파일을 작성하기 때문에 우리가 해당 파일을 사용해야한다는 것을 의미하지는 않습니다. 일반적으로 JAR 파일로 압축하여 대신 사용합니다.