<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### 更復雜的處理器 當你創建用于 javac 注解處理器時,你不能使用 Java 的反射特性,因為你處理的是源代碼,而并非是編譯后的 class 文件。各種 mirror[^3 ] 解決這個問題的方法是,通過允許你在未編譯的源代碼中查看方法、字段和類型。 如下是一個用于提取類中方法的注解,所以它可以被抽取成為一個接口: ```java // annotations/ifx/ExtractInterface.java // javac-based annotation processing package annotations.ifx; import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface ExtractInterface { String interfaceName() default "-!!-"; } ``` **RetentionPolicy** 的值為 **SOURCE**,這是為了在提取類中的接口之后不再將注解信息保留在 class 文件中。接下來的測試類提供了一些公用方法,這些方法可以成為接口的一部分: ```java // annotations/ifx/Multiplier.java // javac-based annotation processing // {java annotations.ifx.Multiplier} package annotations.ifx; @ExtractInterface(interfaceName="IMultiplier") public class Multiplier { public boolean flag = false; private int n = 0; public int multiply(int x, int y) { int total = 0; for(int i = 0; i < x; i++) total = add(total, y); return total; } public int fortySeven() { return 47; } private int add(int x, int y) { return x + y; } public double timesTen(double arg) { return arg * 10; } public static void main(String[] args) { Multiplier m = new Multiplier(); System.out.println( "11 * 16 = " + m.multiply(11, 16)); } } ``` 輸出為: ```java 11 * 16 = 176 ``` **Multiplier** 類(只能處理正整數)擁有一個 `multiply()` 方法,這個方法會多次調用私有方法 `add()` 來模擬乘法操作。` add()` 是私有方法,因此不能成為接口的一部分。其他的方法提供了語法多樣性。注解被賦予 **IMultiplier** 的 **InterfaceName** 作為要創建的接口的名稱。 這里有一個編譯時處理器用于提取有趣的方法,并創建一個新的 interface 源代碼文件(這個源文件將會在下一輪中被自動編譯): ```java // annotations/ifx/IfaceExtractorProcessor.java // javac-based annotation processing package annotations.ifx; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.*; import javax.lang.model.util.*; import java.util.*; import java.util.stream.*; import java.io.*; @SupportedAnnotationTypes( "annotations.ifx.ExtractInterface") @SupportedSourceVersion(SourceVersion.RELEASE_8) public class IfaceExtractorProcessor extends AbstractProcessor { private ArrayList<Element> interfaceMethods = new ArrayList<>(); Elements elementUtils; private ProcessingEnvironment processingEnv; @Override public void init( ProcessingEnvironment processingEnv) { this.processingEnv = processingEnv; elementUtils = processingEnv.getElementUtils(); } @Override public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment env) { for(Element elem:env.getElementsAnnotatedWith( ExtractInterface.class)) { String interfaceName = elem.getAnnotation( ExtractInterface.class).interfaceName(); for(Element enclosed : elem.getEnclosedElements()) { if(enclosed.getKind() .equals(ElementKind.METHOD) && enclosed.getModifiers() .contains(Modifier.PUBLIC) && !enclosed.getModifiers() .contains(Modifier.STATIC)) { interfaceMethods.add(enclosed); } } if(interfaceMethods.size() > 0) writeInterfaceFile(interfaceName); } return false; } private void writeInterfaceFile(String interfaceName) { try( Writer writer = processingEnv.getFiler() .createSourceFile(interfaceName) .openWriter() ) { String packageName = elementUtils .getPackageOf(interfaceMethods .get(0)).toString(); writer.write( "package " + packageName + ";\n"); writer.write("public interface " + interfaceName + " {\n"); for(Element elem : interfaceMethods) { ExecutableElement method = (ExecutableElement)elem; String signature = " public "; signature += method.getReturnType() + " "; signature += method.getSimpleName(); signature += createArgList( method.getParameters()); System.out.println(signature); writer.write(signature + ";\n"); } writer.write("}"); } catch(Exception e) { throw new RuntimeException(e); } } private String createArgList( List<? extends VariableElement> parameters) { String args = parameters.stream() .map(p -> p.asType() + " " + p.getSimpleName()) .collect(Collectors.joining(", ")); return "(" + args + ")"; } } ``` **Elements** 對象實例 **elementUtils** 是一組靜態方法的工具;我們用它來尋找 **writeInterfaceFile()** 中含有的包名。 `getEnclosedElements()`方法會通過指定的元素生成所有的“閉包”元素。在這里,這個類閉包了它的所有元素。通過使用 `getKind()` 我們會找到所有的 **public** 和 **static** 方法,并將其添加到 **interfaceMethods** 列表中。接下來 `writeInterfaceFile()` 使用 **interfaceMethods** 列表里面的值生成新的接口定義。注意,在 `writeInterfaceFile()` 使用了向下轉型到 **ExecutableElement**,這使得我們可以獲取所有的方法信息。**createArgList()** 是一個幫助方法,用于生成參數列表。 **Filer**是 `getFiler()` 生成的,并且是 **PrintWriter** 的一種實例,可以用于創建新文件。我們使用 **Filer** 對象,而不是原生的 **PrintWriter** 原因是,這個對象可以運行 **javac** 追蹤你創建的新文件,這使得它可以在新一輪中檢查新文件中的注解并編譯文件。 如下是一個命令行,可以在編譯的時候使用處理器: ```shell javac -processor annotations.ifx.IfaceExtractorProcessor Multiplier.java ``` 新生成的 **IMultiplier.java** 的文件,正如你通過查看上面處理器的 `println()` 語句所猜測的那樣,如下所示: ```java package annotations.ifx; public interface IMultiplier { public int multiply(int x, int y); public int fortySeven(); public double timesTen(double arg); } ``` 這個類同樣會被 **javac** 編譯(在某一輪中),所以你會在同一個目錄中看到 **IMultiplier.class** 文件。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看