一、介紹
JavaPoet項目可以動態的生成Java文件,這是一個很強大和很動態的方法,使用注解的時候假如需要生成新的Java文件就可以通過這個開源項目實現。
項目地址:https://github.com/square/javapoet
二、JavaPoet常用的類
MethodSpec 代表一個構造函數或方法聲明。
TypeSpec 代表一個類、借口或者枚舉聲明。
FieldSpec 代表一個成員變量,一個字段聲明。
JavaFile 包含一個頂級類的Java文件。
三、引入開源項目
compile 'com.squareup:javapoet:1.8.0'
也可以在開源項目處找到jar文件,下載下來,引入到項目中。
四、生成一個函數
生成一個件簡單的HelloWorld類,有一個靜態方法,只是簡單的輸出“Hello World”字符串。
package com.zhangmiao; import javax.lang.model.element.Modifier; import com.squareup.javapoet.*; import java.io.File; import java.io.IOException; import java.lang.System; public class MainClass { /** * @param args * */ public static void main(String[] args) { // TODO Auto-generated method stub MainClass mainClass = new MainClass(); mainClass.generateHelloWord(); } private void generateHelloWord(){ MethodSpec main = MethodSpec.methodBuilder("show") .addModifiers(Modifier.PUBLIC,Modifier.STATIC) .addStatement("$T.out.println($S)",System.class,"Hello World!") .build(); TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld") .addModifiers(Modifier.PUBLIC) .addMethod(main) .build(); JavaFile javaFile = JavaFile.builder("com.zhangmiao", helloWorld).build(); File outputFile = new File("src/"); //輸出文件 try { javaFile.writeTo(outputFile); javaFile.writeTo(System.out); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
運行結果會顯示整個類的內容,運行MainClass之后,選擇項目點擊右鍵,運行Refresh之后,就可以在包下看到HelloWorld.java類了。
五、調用HelloWorld類的show方法
package com.zhangmiao; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { Class hello = Class.forName("com.zhangmiao.HelloWorld"); hello.newInstance(); Method method = hello.getMethod("show", null); method.invoke(null, null); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block System.out.println("Class Not Found"); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { System.out.println("No Such Method"); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
運行test之后,可以看到運行show方法的結果,打印"Hello World"字符串。
六、注意事項
我的代碼是使用MyEcplise寫的,jdk的版本需要是jdk1.7,如果不是1.7,代碼運行就會報如下錯誤:
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/squareup/javapoet/MethodSpec : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at MainClass.main(MainClass.java:13)
這個時候就需要將jdk的版本修改為1.7。
jdk1.7下載地址:http://download.csdn.net/download/chun201010/7824469
MyEcplise配置jdk1.7請參考另外一篇文章:http://www.cnblogs.com/zhangmiao14/p/6932330.html
還有一些其他生成類和方法的方法,比如for循環的寫法,直接使用addCode()方法生成方法內容,設置返回值、參數等等,這些細節可以參考源碼地址的README.md文件,很詳細,本文只是簡單的使用一下。
