Java 使用正确编码进行内部编译?

Java 使用正确编码进行内部编译?,java,encoding,compiler-construction,internal,Java,Encoding,Compiler Construction,Internal,我有一个程序,将字符串写入.java文件,使用javax.tools将.java文件编译成.class文件,然后使用修改后的类加载器尝试获取类的可运行的实例(通过将其转换为字节数组并使用ClassLoader.defineClass获取实例)。但是,我有个问题。当程序试图获取该类的实例时,它会注意到该类的编译方式不正确。我得到一个ClassFormatError,它读取类文件中不兼容的魔法值1885430635。以下是我的代码(目前相当草率): import java.io.*; 导入java.

我有一个程序,将字符串写入.java文件,使用
javax.tools
将.java文件编译成.class文件,然后使用修改后的类加载器尝试获取类的
可运行的
实例(通过将其转换为字节数组并使用
ClassLoader.defineClass
获取实例)。但是,我有个问题。当程序试图获取该类的实例时,它会注意到该类的编译方式不正确。我得到一个
ClassFormatError
,它读取类文件中不兼容的魔法值1885430635。以下是我的代码(目前相当草率):

import java.io.*;
导入java.security.SecureClassLoader;
公共类增强ClassLoader扩展了SecureClassLoader
{
公共对象createObjectFromFile(字符串文件名)抛出
实例化异常、IOException、IllegaAccessException
{
文件=新文件(文件名);
定义包(“compClassPack”,null,null,null,null,null,file.toURI().toURL());
byte[]classBytes=null;
//ReadFileToByteArray
{
FileInputStream fis=新的FileInputStream(文件);
int size=(int)file.length();
classBytes=新字节[大小];
整数偏移=0;
int-readed;
而(offset

import java.io.*;
导入javax.tools.*;
公共班机
{
公共静态void main(字符串[]args)引发异常
{
File File=新文件(“Sample.java”);
FileWriter fw=新的FileWriter(文件);
BufferedWriter bw=新的BufferedWriter(fw);
字符串代码=
“包compClassPack;\n”+
“公共类示例实现可运行\n”+
“{\n”+
“公共样本(){}\n\n”+
“公共静态void main(字符串[]参数)\n”+
“{\n”+
“新建示例()。运行();\n”+
“}\n\n”+
“公共无效运行()\n”+
“{\n”+
“System.out.println(\“成功了!:D\”);\n”+
“}\n”+
"}";
for(字节ch:code.getBytes())
{
如果((char)ch!='\n')
写入((字符)ch);
其他的
换行符();
}
bw.flush();
bw.close();
JavaCompiler=ToolProvider.getSystemJavaCompiler();
DiagnosticCollector diagnostics=新建DiagnosticCollector();
StandardJavaFileManager fileManager=compiler.getStandardFileManager(诊断,null,null);

Iterable您的字节数组不是有效的字节码。如果是,它将以魔术字符串(十六进制)开始。相反,您的第一个字节是
1885430635
(十进制),它是十六进制
0x7061636b
,一次读取一个字节,给出ASCII字符
pack
,这只是包声明的开始


换句话说,您试图加载一个文本文件,就好像它是字节码一样,而Java显然无法从这样的字节流构造任何类。

是的,我知道……您知道有什么可以让我做我想做的吗?这是一个非常简单的教程
import java.io.*;
import java.security.SecureClassLoader;

public class EnhancedClassLoader extends SecureClassLoader
{
    public Object createObjectFromFile(String fileName) throws 
    InstantiationException, IOException, IllegalAccessException
    {
        File file = new File(fileName);
        definePackage("compClassPack", null, null, null, null, null, null, file.toURI().toURL());
        byte[] classBytes = null;
        //ReadFileToByteArray
        {
            FileInputStream fis = new FileInputStream(file);
            int size = (int)file.length();
            classBytes = new byte[size];
            int offset = 0;
            int readed;
            while (offset < size && (readed = fis.read(classBytes, offset, size - offset)) != -1)
            {
                offset += readed;
            }
        fis.close();
        }
        Class<?> clazz = defineClass(null, classBytes, 0, classBytes.length);
            //The error is thrown here! ^^^

        return clazz.newInstance();
    }
}
import java.io.*;
import javax.tools.*;

public class Main
{
    public static void main(String[] args)throws Exception
    {
        File file = new File("Sample.java");
        FileWriter fw = new FileWriter(file);
        BufferedWriter bw = new BufferedWriter(fw);

        String code =
                "package compClassPack;\n" +
                "public class Sample implements Runnable\n" +
                "{\n" +
                "    public Sample(){}\n\n" +
                "    public static void main(String[] args)\n" +
                "    {\n" +
                "        new Sample().run();\n" +
                "    }\n\n" +
                "    public void run()\n" +
                "    {\n" +
                "        System.out.println(\"It worked! :D\");\n" +
                "    }\n" +
                "}";

        for(byte ch : code.getBytes())
        {
            if((char)ch!='\n')
                bw.write((char)ch);
            else
                bw.newLine();
        }
        bw.flush();
        bw.close();

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(file);
        JavaCompiler.CompilationTask ct = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits);
        ct.call();

        for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics())
            System.out.format("Error on line %d in %d%n",
                    diagnostic.getLineNumber(),
                    ((FileObject)diagnostic.getSource()).toUri());

        fileManager.close();

        EnhancedClassLoader loader = new EnhancedClassLoader();
        Runnable runs = (Runnable) loader.createObjectFromFile(file.getAbsolutePath());
        runs.run(); 
    }
}