java resource放入的文件没有生成在classes中_从零开始写文本编辑器(二十三):用散列码生成R文件...

58ea314b02f3c36994ae8c50f8812848.png

前言

现在的资源调用都是用hashcode,但是写了很多的magic text,这样很“脏”。android中使用了R文件来定义资源的散列值,通过加一层R,让magic text消失,android是用名为aapt的工具来实现的。我就写一个名为RMake的类来完成。

本篇主要说明散列思想,及应用于字符串资源的编译索引。

为什么要用散列码?R文件的作用是什么?

其实学过《离散数学》就不会有这类问题了。这跟1+1为什么=2一样。

为什么用散列码?

答:《离散数学》

R文件的作用是什么?

R文件是一个静态类,它有静态的内部类,一般为id/string/style/layout等。这是一种编译技术的产物,用代码生成代码。

在本例中是“用xml代码生成java代码”。

这这样就能引用java代码来间接引用xml的资源。

映射的函数就是离散数学中的散列函数。本例中直接使用java.lang.String.hashCode()。

/**

算法在JDK源码的注释文档中写明,这里就不解读了,纯数学表达式。

实现R文件的编译

没那么难,先写一个粗糙的输出

@Override

输入:XML文件内容

<?xml version="1.0" encoding="UTF-8"?>

输出:控制台文本

file, 文件, 3143036
code, 代码, 3059181
edit, 编辑, 3108362
help, 帮助, 3198785
...

格式化为R类的源代码

@Override

输出:

public 

有关R辅助用例

检验name的合法,目前我只验证了不能为java关键字。

package 

更多的验证,后续再按优先级添加,现在不关心。

看一下添加验证的输出

...
    

779db6aa26193a60c9bfc24d5cbe5ed3.png

复制到R文件中(是的,我没有写fileAutoWrite的代码,所以现在还是手工复制)

package 

同步的,要调整XML的资源加载,容器还是HashMap,但泛型类型为<Integer, String>

package 

使用R文件

d70c3fa84e1380b9ef587bcc93f84bb0.png

与其说是编程的快乐,不如说是数字的魅力。

数学家天下无敌!

我爱数学~

我用编程来应用数学~快乐~

以上~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态生成class文件并将其放入Spring Boot的胖包可以通过以下步骤完成: 1. 使用JavaClassLoader类动态加载一个类。 2. 使用JavaJavaCompiler类将Java文件编译成class文件。 3. 将生成class文件复制到Spring Boot的胖包。 4. 在Spring Boot应用程序使用新生成的类。 以下是一个示例代,可以动态生成一个名为"HelloWorld"的类,并将其放入Spring Boot的胖包: ```java import java.io.*; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import javax.tools.JavaCompiler; import javax.tools.ToolProvider; public class DynamicClassLoading { public static void main(String[] args) { try { // 动态加载一个类 String className = "HelloWorld"; String classSource = "public class HelloWorld { public void sayHello() { System.out.println(\"Hello, world!\"); } }"; Class<?> helloWorldClass = createClass(className, classSource); // 将生成class文件复制到Spring Boot的胖包 String jarFilePath = "path/to/your/springboot/fatjar.jar"; Path jarPath = Paths.get(jarFilePath); byte[] classBytes = Files.readAllBytes(helloWorldClass.getProtectionDomain().getCodeSource().getLocation().toURI().relativize(helloWorldClass.getResource(className + ".class").toURI())); Files.write(Paths.get("temp/" + className + ".class"), classBytes); try (FileSystem fileSystem = FileSystems.newFileSystem(jarPath, null)) { Path pathInJar = fileSystem.getPath("/BOOT-INF/classes/" + className + ".class"); Files.write(pathInJar, classBytes); } // 在Spring Boot应用程序使用新生成的类 URL[] urls = new URL[] { new URL("file:" + jarFilePath) }; ClassLoader classLoader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader()); Class<?> loadedClass = classLoader.loadClass(className); Object instance = loadedClass.newInstance(); loadedClass.getMethod("sayHello").invoke(instance); } catch (Exception e) { e.printStackTrace(); } } private static Class<?> createClass(String className, String classSource) throws IOException { // 使用JavaCompiler类将Java文件编译成class文件 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (compiler == null) { throw new RuntimeException("Java compiler unavailable. Make sure you're running a JDK, not just a JRE."); } DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); JavaFileObject sourceFile = new SimpleJavaFileObject(URI.create(className), JavaFileObject.Kind.SOURCE) { @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return classSource; } }; JavaCompiler.CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, Arrays.asList(sourceFile)); if (!task.call()) { for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { System.out.format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource().toUri()); System.out.println(diagnostic.getMessage(Locale.getDefault())); } throw new RuntimeException("Failed to compile class"); } // 使用JavaClassLoader类动态加载一个类 byte[] classBytes = Files.readAllBytes(Paths.get(className + ".class")); Class<?> loadedClass = new ByteArrayClassLoader(className, classBytes).loadClass(className); return loadedClass; } private static class ByteArrayClassLoader extends ClassLoader { private final String className; private final byte[] classBytes; public ByteArrayClassLoader(String className, byte[] classBytes) { this.className = className; this.classBytes = classBytes; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { if (className.equals(name)) { return defineClass(className, classBytes, 0, classBytes.length); } return super.findClass(name); } } } ``` 在这个示例,我们首先动态加载了一个名为"HelloWorld"的类,然后将生成class文件复制到Spring Boot的胖包。接下来,我们使用URLClassLoader动态加载生成的类,并在Spring Boot应用程序使用它。当你运行这个程序时,它将在控制台输出"Hello, world!"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值