• JavaPoet开源项目的使用


    一、介绍

      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文件,很详细,本文只是简单的使用一下。

  • 相关阅读:
    5 粘包现象与解决方案
    4 Socket代码实例
    协程与多路io复用epool关系
    基于selector的socket并发
    基于select类型多路IO复用,实现简单socket并发
    协程实现多并发socket,跟NGINX一样
    利用协程实现简单爬虫
    协程
    进程池pool
    进程锁 Lock
  • 原文地址:https://www.cnblogs.com/zhangmiao14/p/6933258.html
Copyright © 2020-2023  润新知