精华内容
下载资源
问答
  • 答案是肯定的,Java中的接口,实现类都会编译成.class文件

     答案是肯定的,Java中的接口,实现类都会编译成.class文件的

    展开全文
  • 使用JavaCompiler 编译 Java文件

    千次阅读 2019-05-31 20:49:35
    从1.6版本的JDK开始,JDK提供了标准的包(javax.tools)可以方便的调用JVM的编译器,可以方便的通过JVM的编译器来编译java源文件。 JDK提供的调用接口JavaCompiler类,该类及CompilerAPI相关类在JDK的tools.jar...
          从1.6版本的JDK开始,JDK提供了标准的包(javax.tools)可以方便的调用JVM的编译器,可以方便的通过JVM的编译器来编译java源文件。
       JDK提供的调用接口是JavaCompiler类,该类及CompilerAPI相关类在JDK的tools.jar包中。
       
       注意:在开发过程中由于使用的开发工具(IntelliJ IDEA或Eclipse)默认加载jdk包中的jre下的lib中的jar,请检查是否将lib下的tool.jar引入,
            如果没有引用将导致ClassNotFoundException异常
    

    编译java文件demo

     /**
         * 编译java文件,使用StandardJavaFileManager编译Java源程式
         * @param encoding 编译编码
         * @param filePath 文件或者目录(若为目录,自动递归编译)
         * @param diagnostics 存放编译过程中的错误信息
         * @return
         * @throws Exception
         */
        public boolean compiler(String encoding, String filePath,String outputFile, DiagnosticCollector<JavaFileObject> diagnostics)  throws Exception{
    
            String sourceDir=filePath;//java源文件存放目录
            String targetDir="";//编译后class类文件存放目录
    
            // 获取编译器实例
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            // 获取标准文件管理器实例
            StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, Charset.forName(encoding));
            try {
                //得到编译关联的jar
                List<File> jars = new ArrayList<File>();
                getJarFiles(new File(filePath),jars);
                // 得到filePath目录下的所有java源文件
                File sourceFile = new File(sourceDir);
                List<File> sourceFileList = new ArrayList<File>();
                getSourceFiles(sourceFile, sourceFileList);
                // 没有java文件,直接返回
                if (sourceFileList.size() == 0) {
                    System.out.println(sourceDir + "目录下查找不到任何java文件");
                    return false;
                }
                //加载依赖的jar文件和依赖的class文件
                List<File> dependencies = new ArrayList<File>();
                dependencies.addAll(jars);
                //dependencies.addAll(sourceFileList);
                fileManager.setLocation(StandardLocation.CLASS_PATH,dependencies);
                fileManager.setLocation(StandardLocation.SOURCE_PATH,sourceFileList);
                //编译后输出的地址
                fileManager.setLocation(StandardLocation.CLASS_OUTPUT,Arrays.asList(new File[]{new File(outputFile)}));
    
                // 获取要编译的编译单元
                Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFileList);
                /**
                 * 编译选项,在编译java文件时,编译程序会自动的去寻找java文件引用的其他的java源文件或者class。
                 * -sourcepath选项就是定义java源文件的查找目录,有时我们编译一个Java源程式文件,而这个源程式文件需要另几个Java文件,
                 *            而这些Java文件又在另外一个目录,那么这就需要为编译器指定这些文件所在的目录。
                 * -classpath选项就是定义class文件的查找目录。
                 * -d 是用来指定存放编译生成的.class文件的路径
                 */
                //Iterable<String> options = Arrays.asList("-encoding", encoding, "-classpath", jars.toString(), "-d", targetDir, "-sourcepath", sourceDir);
                Iterable<String> options = Arrays.asList("-encoding", encoding,"-source","1.8");
                JavaCompiler.CompilationTask compilationTask = compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits);
                //运行编译任务
                return compilationTask.call();
            }finally {
                fileManager.close();
            }
        }
    

    查找该目录下的所有的java文件

        private void getSourceFiles(File sourceFile, List<File> sourceFileList) throws Exception {
            if (sourceFile.exists() && sourceFileList != null) {//文件或者目录必须存在
                if (sourceFile.isDirectory()) {// 若file对象为目录
                    File[] childrenFiles=sourceFile.listFiles((pathname->{
                        if (pathname.isDirectory()) {
                            return true;
                        }else{
                            String name = pathname.getName();
                            if (name.endsWith(".java") ? true : false) {
                                return true;
                            }
                            return false;
                        }
                    }));
                    // 递归调用
                    for (File childFile : childrenFiles) {
                        getSourceFiles(childFile, sourceFileList);
                    }
                }else{
                    //若file对象为文件
                    String name = sourceFile.getName();
                    if (name.endsWith(".java") ? true : false) {
                        //System.out.println(sourceFile.getAbsolutePath());
                        sourceFileList.add(sourceFile);
                    }
                }
            }
        }
    

    递归查找该目录下的所有的jar文件

    private void getJarFiles(File jarFile,List<File> jars) throws Exception {
            if (jarFile.exists() && jarFile != null) {//文件或者目录必须存在
                if (jarFile.isDirectory()) {// 若file对象为目录
                    File[] childrenFiles= jarFile.listFiles((pathname) -> {
                            if (pathname.isDirectory()) {
                                return true;
                            } else {
                                String name = pathname.getName();
                                if (name.endsWith(".jar") ? true : false) {
                                    return true;
                                }
                                return false;
                            }
                        });
                    // 递归调用
                    for (File childFile : childrenFiles) {
                        getJarFiles(childFile, jars);
                    }
                }else{
                    String name = jarFile.getName();
                    if (name.endsWith(".jar") ? true : false) {
                       // System.out.println(jarFile.getAbsolutePath());
                        jars.add(jarFile);
                    }
                }
            }
        }
    

    调用

    public static void main(String[] objs){
       DynamicCompilerTool tool = new DynamicCompilerTool();
       String outputFile = target.getAbsolutePath()+File.separator+"WebContent"+File.separator+"WEB-INF"+File.separator+"classes";
       File cls=new File(outputFile);
       if(!cls.exists()){
            cls.mkdir();
        }
        String encoding = "utf-8";
        boolean b = tool.compiler(encoding, javaProject.getAbsolutePath(), outputFile, diagnostics);
         if(!b){
    	    StringJoiner rs=new StringJoiner(System.getProperty("line.separator"));
    	       for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
    	           rs.add(String.format("%s:%s[line %d column %d]-->%s%n", diagnostic.getKind(), diagnostic.getSource(), diagnostic.getLineNumber(),
    	                   diagnostic.getColumnNumber(),
    	                   diagnostic.getMessage(null)));
    	      System.out.println("编译失败,原因:"+rs.toString());
    	}else{
    	   System.out.println("编译成功");
        }
    }
    
    展开全文
  • .java文件编译后会产生那些.class文件

    千次阅读 2017-08-22 19:44:04
    1,对于普通的Java文件,里面只有一个类,也就是一个class,(注意:e->表达式...2,对于复杂一点的.java文件,例如里面有除了公共类以外的,与公共类平行的类或接口,那么,有多少个类或接口,就会编译出多少个.class

    1,对于普通的Java文件,里面只有一个类,也就是一个class,(注意:e->表达式也应该不能有),那么编译出来的就只有一个类名.class

        e.g. public class Person{

    }

    编译后:就是Person.class奋斗


    2,对于复杂一点的.java文件,例如里面有除了公共类以外的,与公共类平行的类或接口,那么,有多少个类或接口,就会编译出多少个.class文件

    e.g. public class Person{

    }

    class Tool{

    }

    interface Communication{

    }

    编译后:就是Person.class   Tool.class   Communication.class


    3,在1.2的基础上,添加一些内部类会怎样疑问?内部类和内部接口将会按照公共类名 + $ +内部类名.class的格式产生相应数量的class文件

    e.g.public class Person{

    class Tool{}

    interface Communication{}

    }

    编译后:就是Person.class  Person$Tool.class  Person$Communication.class


    展开全文
  • 深入理解java编译后的字节码文件

    千次阅读 2018-04-19 17:15:53
    从我们写的java文件到通过编译器编译java字节码文件(也就是.class文件),这个过程是java编译过程;而我们的java虚拟机执行的就是字节码文件。不论该字节码文件来自何方,由哪种编译器编译...

    也许你写了无数行的代码,也许你能非常溜的使用高级语言,但是你未必了解那些高级语言的执行过程。例如大行其道的Java。

    Java号称是一门“一次编译到处运行”的语言,但是我们对这句话的理解深度又有多少呢?从我们写的java文件到通过编译器编译成java字节码文件(也就是.class文件),这个过程是java编译过程;而我们的java虚拟机执行的就是字节码文件。不论该字节码文件来自何方,由哪种编译器编译,甚至是手写字节码文件,只要符合java虚拟机的规范,那么它就能够执行该字节码文件。那么本文主要讲讲java字节码文件相关知识。接下来我们通过具体的Demo来深入理解:

    1 首先我们来写一个java源文件

    javasrc.png

    上面是我们写的一个java程序,很简单,只有一个成员变量a以及一个方法testMethod() 。

    2 接下来我们用javac命令或者ide工具将该java源文件编译成java字节码文件。

    demo.png

    上图是编译好的字节码文件,我们可以看到一堆16进制的字节。如果你使用IDE去打开,也许看到的是已经被反编译的我们所熟悉的java代码,而这才是纯正的字节码,这也是我们今天需要讲的内容重点。

    也许你会对这样一堆字节码感到头疼,不过没关系,我们慢慢试着你看懂它,或许有不一样的收获。在开始之前我们先来看一张图

    java_byte.jpeg

    这张图是一张java字节码的总览图,我们也就是按照上面的顺序来对字节码进行解读的。一共含有10部分,包含魔数,版本号,常量池等等,接下来我们按照顺序一步一步解读。

    3.1 魔数

    从上面的总览图中我们知道前4个字节表示的是魔数,对应我们Demo的是 0XCAFE BABE。什么是魔数?魔数是用来区分文件类型的一种标志,一般都是用文件的前几个字节来表示。比如0XCAFE BABE表示的是class文件,那么有人会问,文件类型可以通过文件名后缀来判断啊?是的,但是文件名是可以修改的(包括后缀),那么为了保证文件的安全性,将文件类型写在文件内部来保证不被篡改。
    从java的字节码文件类型我们看到,CAFE BABE翻译过来是咖啡宝贝之意,然后再看看java图标。

    java_icon.png

    CAFE BABE = 咖啡。

    3.2 版本号

    我们识别了文件类型之后,接下来要知道版本号。版本号含主版本号和次版本号,都是各占2个字节。在此Demo种为0X0000 0033。其中前面的0000是次版本号,后面的0033是主版本号。通过进制转换得到的是次版本号为0,主版本号为51。
    从oracle官方网站我们能够知道,51对应的正式jdk1.7,而其次版本为0,所以该文件的版本为1.7.0。如果需要验证,可以在用java –version命令输出版本号,或者修改编译目标版本–target重新编译,查看编译后的字节码文件版本号是否做了相应的修改。

    至此,我们共了解了前8字节的含义,下面讲讲常量池相关内容。

    3.3 常量池

    紧接着主版本号之后的就是常量池入口。常量池是Class文件中的资源仓库,在接下来的内容中我们会发现很多地方会涉及,如Class Name,Interfaces等。常量池中主要存储2大类常量:字面量和符号引用。字面量如文本字符串,java中声明为final的常量值等等,而符号引用如类和接口的全局限定名,字段的名称和描述符,方法的名称和描述符。

    为什么需要类和接口的全局限定名呢?系统引用类或者接口的时候不是通过内存地址进行操作吗?这里大家仔细想想,java虚拟机在没有将类加载到内存的时候根本都没有分配内存地址,也就不存在对内存的操作,所以java虚拟机首先需要将类加载到虚拟机中,那么这个过程设计对类的定位(需要加载A包下的B类,不能加载到别的包下面的别的类中),所以需要通过全局限定名来判别唯一性。这就是为什么叫做全局,限定的意思,也就是唯一性。

    在进行具体常量池分析之前,我们先来了解一下常量池的项目类型表:

    jvm_constant.png

    上面的表中描述了11中数据类型的结构,其实在jdk1.7之后又增加了3种(CONSTANT_MethodHandle_info,CONSTANT_MethodType_info以及CONSTANT_InvokeDynamic_info)。这样算起来一共是14种。接下来我们按照Demo的字节码进行逐一翻译。

    0×0015:由于常量池的数量不固定(n+2),所以需要在常量池的入口处放置一项u2类型的数据代表常量池数量。因此该16进制是21,表示有20项常量,索引范围为1~20。明明是21,为何是20呢?因为Class文件格式规定,设计者就讲第0项保留出来了,以备后患。从这里我们知道接下来我们需要翻译出20项常量。
    Constant #1 (一共有20个常量,这是第一个,以此类推…)
    0x0a-:从常量类型表中我们发现,第一个数据均是u1类型的tag,16进制的0a是十进制的10,对应表中的MethodRef_info。
    0x-00 04-:Class_info索引项#4
    0x-00 11-:NameAndType索引项#17
    Constant #2
    0x-09: FieldRef_info
    0×0003 :Class_info索引项#3
    0×0012:NameAndType索引项#18
    Constant #3
    0×07-: Class_info
    0x-00 13-: 全局限定名常量索引为#19
    Constant #4
    0x-07 :Class_info
    0×0014:全局限定名常量索引为#20
    Constant #5
    0×01:Utf-8_info
    0x-00 01-:字符串长度为1(选择接下来的一个字节长度转义)
    0x-61:”a”(十六进制转ASCII字符)
    Constant #6
    0×01:Utf-8_info
    0x-00 01:字符串长度为1
    0x-49:”I”
    Constant #7
    0×01:Utf-8_info
    0x-00 06:字符串长度为6
    0x-3c 696e 6974 3e-:”<init>”
    Constant #8
    0×01 :UTF-8_info
    0×0003:字符串长度为3
    0×2829 56:”()V”
    Constant #9
    0x-01:Utf-8_info
    0×0004:字符串长度为4
    0x436f 6465:”Code”
    Constant #10
    0×01:Utf-8_info
    0×00 0f:字符串长度为15
    0x4c 696e 654e 756d 6265 7254 6162 6c65:”LineNumberTable”
    Constant #11
    ox01: Utf-8_info
    0×00 12字符串长度为18
    0x-4c 6f63 616c 5661 7269 6162 6c65 5461 626c 65:”LocalVariableTable”
    Constant #12
    0×01:Utf-8_info
    0×0004 字符串长度为4
    0×7468 6973 :”this”
    Constant #13
    0×01:Utf-8_info
    0x0f:字符串长度为15
    0x4c 636f 6d2f 6465 6d6f 2f44 656d 6f3b:”Lcom/demo/Demo;”
    Constant #14
    0×01:Utf-8_info
    0×00 0a:字符串长度为10
    ox74 6573 744d 6574 686f 64:”testMethod”
    Constant #15
    0×01:Utf-8_info
    0x000a:字符串长度为10
    0x536f 7572 6365 4669 6c65 :”SourceFile”
    Constant #16
    0×01:Utf-8_info
    0×0009:字符串长度为9
    0x-44 656d 6f2e 6a61 7661 :”Demo.java”
    Constant #17
    0x0c :NameAndType_info
    0×0007:字段或者名字名称常量项索引#7
    0×0008:字段或者方法描述符常量索引#8
    Constant #18
    0x0c:NameAndType_info
    0×0005:字段或者名字名称常量项索引#5
    0×0006:字段或者方法描述符常量索引#6
    Constant #19
    0×01:Utf-8_info
    0×00 0d:字符串长度为13
    0×63 6f6d 2f64 656d 6f2f 4465 6d6f:”com/demo/Demo”
    Constant #20
    0×01:Utf-8_info
    0×00 10 :字符串长度为16
    0x6a 6176 612f 6c61 6e67 2f4f 626a 6563 74 :”java/lang/Object”
    到这里为止我们解析了所有的常量。接下来是解析访问标志位。

    3.4 Access_Flag 访问标志

    访问标志信息包括该Class文件是类还是接口,是否被定义成public,是否是abstract,如果是类,是否被声明成final。通过上面的源代码,我们知道该文件是类并且是public。

    access_flag.png

    0x 00 21:是0×0020和0×0001的并集。其中0×0020这个标志值涉及到了字节码指令,后期会有专题对字节码指令进行讲解。期待中……

    3.5 类索引

    类索引用于确定类的全限定名
    0×00 03 表示引用第3个常量,同时第3个常量引用第19个常量,查找得”com/demo/Demo”。#3.#19

    3.6父类索引

    0×00 04 同理:#4.#20(java/lang/Object)

    3.7 接口索引

    通过java_byte.jpeg图我们知道,这个接口有2+n个字节,前两个字节表示的是接口数量,后面跟着就是接口的表。我们这个类没有任何接口,所以应该是0000。果不其然,查找字节码文件得到的就是0000。

    3.8 字段表集合

    字段表用于描述类和接口中声明的变量。这里的字段包含了类级别变量以及实例变量,但是不包括方法内部声明的局部变量。
    同样,接下来就是2+n个字段属性。我们只有一个属性a,按道理应该是0001。查找文件果不其然是0001。
    那么接下来我们要针对这样的字段进行解析。附上字段表结构图

    字段表结构.png

    0×00 02 :访问标志为private(自行搜索字段访问标志)
    0×00 05 : 字段名称索引为#5,对应的是”a”
    0x 00 06 :描述符索引为#6,对应的是”I”
    0x 00 00 :属性表数量为0,因此没有属性表。
    tips:一些不太重要的表(字段,方法访问标志表)可以自行搜索,这里就不贴出来了,防止篇幅过大。

    3.9 方法

    我们只有一个方法testMethod,按照道理应该前2个字节是0001。通过查找发现是0×00 02。这是什么原因,这代表着有2个方法呢?且继续看……

    方法表结构.png

    上图是一张方法表结构图,按照这个图我们分析下面的字节码:

    第1个方法:

    0×00 01:访问标志 ACC_PUBLIC,表明该方法是public。(可自行搜索方法访问标志表)
    0×00 07:方法名索引为#7,对应的是”<init>”
    0×00 08:方法描述符索引为#8,对应的是”()V”
    0×00 01:属性表数量为1(一个属性表)
    那么这里涉及到了属性表。什么是属性表呢?可以这么理解,它是为了描述一些专有信息的,上面的方法带有一张属性表。所有属性表的结构如下图:
    一个u2的属性名称索引,一个u2的属性长度加上属性长度的info。
    虚拟机规范预定义的属性有很多,比如Code,LineNumberTable,LocalVariableTable,SourceFile等等,这个网上可以搜索到。

    属性表结构.png

    按照上面的表结构解析得到下面信息:
    0×0009:名称索引为#9(“Code”)。
    0×000 00038:属性长度为56字节。
    那么接下来解析一个Code属性表,按照下图解析

    code.png

    前面6个字节(名称索引2字节+属性长度4字节)已经解析过了,所以接下来就是解析剩下的56-6=50字节即可。
    0×00 02 :max_stack=2
    0×00 01 : max_locals=1
    0×00 0000 0a : code_length=10
    0x2a b700 012a 04b5 0002 b1 : 这是code代码,可以通过虚拟机字节码指令进行查找。
    2a=aload_0(将第一个引用变量推送到栈顶)
    b7=invokespecial(调用父类构造方法)
    00=什么都不做
    01 =将null推送到栈顶
    2a=同上
    04=iconst_1 将int型1推送到栈顶
    b5=putfield 为指定的类的实例变量赋值
    00= 同上
    02=iconst_m1 将int型-1推送栈顶
    b1=return 从当前方法返回void
    整理,去除无动作指令得到下面
    0 : aload_0
    1 : invokespecial
    4 : aload_0
    5 : iconst_1
    6 : putfield
    9 : return
    关于虚拟机字节码指令这块内容,后期会继续深入下去…… 目前只需要了解即可。接下来顺着Code属性表继续解析下去:
    0×00 00 : exception_table_length=0
    0×00 02 : attributes_count=2(Code属性表内部还含有2个属性表)
    0×00 0a: 第一个属性表是”LineNumberTable”

    LineNumberTable.png

    0×00 0000 0a : “属性长度为10″
    0×00 02 :line_number_table_length=2
    line_number_table是一个数量为line_number_table_length,类型为line_number_info的集合,line_number_info表包括了start_pc和line_number两个u2类型的数据项,前者是字节码行号,后者是Java源码行号
    0×00 00 : start_pc =0
    0×00 03 : end_pc =3
    0×00 04 : start_pc=4
    0×00 04 : end_pc=4

    0×00 0b 第二个属性表是:”LocalVariableTable”


    local_variable_table.png

    local_variable_info.png

    0×00 0000 0c:属性长度为12
    0×00 01 : local_variable_table_length=1
    然后按照local_variable_info表结构进行解析:
    0×00 00 : start_pc=0
    0×00 0a:length=10
    0x000c : name_index=”this”
    0x000d : descriptor_index #13 (“Lcom/demo/Demo”)
    0000 index=0
    //——-到这里第一个方法就解析完成了——-//
    Method(<init>)–1个属性Code表-2个属性表(LineNumberTable ,LocalVariableTable)接下来解析第二个方法

    第2个方法:

    0×00 04:”protected”
    0×00 0e: #14(”testMethod”)
    0×00 08 : “()V”
    0×0001 : 属性数量=1
    0×0009 :”Code”
    0×0000 002b 属性长度为43
    解析一个Code表
    0000 :max_stack =0
    0001 : max_local =1
    0000 0001 : code_length =1
    0xb1 : return(该方法返回void)
    0×0000 异常表长度=0
    0×0002 属性表长度为2
    //第一个属性表
    0x000a : #10,LineNumberTable
    0×0000 0006 : 属性长度为6
    0×0001 : line_number_length = 1
    0×0000 : start_pc =0
    0×0008 : end_pc =8
    //第二个属性表
    0x000b : #11 ,LocalVariableTable
    0×0000 000c : 属性长度为12
    0×0001 : local_variable_table_length =1
    0×0000 :start_pc = 0
    0×0001: length = 1
    0x000c : name_index =#12 “this”
    0x000d : 描述索引#13 “Lcom/demo/Demo;”
    0000 index=0

    //到这里为止,方法解析都完成了,回过头看看顶部解析顺序图,我们接下来就要解析Attributes了。

    3.10 Attribute

    0×0001 :同样的,表示有1个Attributes了。
    0x000f : #15(“SourceFile”)
    0×0000 0002 attribute_length=2
    0×0010 : sourcefile_index = #16(“Demo.java”)
    SourceFile属性用来记录生成该Class文件的源码文件名称。

    source_file.jpeg

    4 另话

    其实,我们写了这么多确实很麻烦,不过这种过程自己体验一遍的所获所得还是不同的。现在,使用java自带的反编译器来解析字节码文件。
    javap -verbose Demo //不用带后缀.class

    javap_result.png

    5 总结

    到此为止,讲解完成了class文件的解析,这样以后我们也能看懂字节码文件了。了解class文件的结构对后面进一步了解虚拟机执行引擎非常重要,所以这是基础并重要的一步。

    展开全文
  • import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; public class Test { public static void main(String[] args) { String class...
  • 在protobuf学习(2):.proto文件的定义学习了.proto文件的定义之后,本章来介绍一下怎么通过protoc(protobuf编译器)来生成Java代码。 protoc的下载与安装 在protobuf官网Basics:java中,找到Compiling Your ...
  • linux上编译Java接口文件生成的libgmssljni.so库文件放在打印的java.library.path路径下。测试时java文件下,我自己写了个Test.java文件,可以成功调用java接口方法
  • 不错的好文章,直接调式Javac编译过程来说明怎样将.java 文件转成.class文件,这其中发生了什么。 下面我们详细了解Java前端编译Java源代码编译成Class文件的过程;我们从官方JDK提供的前端编译器javac入手,用...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    文章目录Java概述何为编程什么是Javajdk1.5之后的三大版本JVM、JRE和JDK的关系什么是跨平台性?原理是什么Java语言有哪些特点什么是字节码?采用字节码的最大好处是什么什么是Java程序的主类?应用程序和小程序的...
  • ClassI 接口 编译之后,如图: 可以证明的是 如果再一个java文件中有多个类,除去内部类,剩下的每个普通类都会生成一个class文件 生成完的class文件: public class ClassD { ClassB b; public ClassD() { } public ...
  • 我新入公司第一次听说增量上线,所谓增量上线就是把你更改的java文件在本地编译成为.class文件,然后直接将.class文件扔到服务器上面去。这就是问题所在了,我在一个java类里面引用了一个内部类,然后增量上线的时候...
  • 在上篇文章中了解到了Java前端编译 JIT编译 AOT编译各有什么优点和缺点,下面详细了解Java前端编译Java源代码编译成Class文件的过程;我们从官方JDK提供的前端编译器javac入手,用javac编译一些测试程序,调试跟踪...
  • protobuf通过protoc编译生成java代码

    千次阅读 2019-11-08 17:01:49
    1、配置 在项目的.proto 的头部添加 syntax = “proto3”; option java_package = “com.XXX.model”;...option java_outer_classname= “TboxMessageProto”; 2、转换 protoc --java_out=./ XX.proto ...
  • c++生成java接口,jni技术

    千次阅读 2018-12-17 20:21:15
    c++ 生成java 接口最本质的方法是通过jni 技术,jni 技术可以实现java 和c++的互相调用 那么生成so 具体用什么方法好呢? 我所知道的有四种方式 1: 写andorid 的android.mk 文件,之前在eclipse 中使用过,mk 文件就...
  • java文件编译后包含的信息

    千次阅读 2014-12-13 22:28:03
    java编译后生成 class文件,包括三个部分:一、类信息一部分是描述类的信息,包括类的名字、修饰符(public或private)、父类、接口以及注解(annotation)。二、变量信息一部分是描述类变量的信息,包括每个变量的...
  • 从JDK5开始,Java增加了注解,注解是代理里特殊的标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用注解,开发人员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析...
  • as创建aidl文件生成Java代码为空as创建aidl生成Java文件为空在这里mark一下我自己发现的解决方案:经过多次尝试之后,我然后在aidl文件里面写了这样一句代码,生成Java成功我之前一直报错得代码是这样子的发现有什么...
  • Java WebService接口生成和调用 图文详解

    万次阅读 多人点赞 2017-04-22 10:48:24
    写调用方法调用下载下来的WebService中的java类中的方法; 示例: import com.pcm.ws.jws.JwsServiceHello; import com.pcm.ws.jws.JwsServiceHelloService; /** * * Title: JwsClientHello * ...
  • Java编译(二)Java前端编译Java源代码编译成Class文件的过程 在上篇文章《Java三种编译方式:前端编译 JIT编译 AOT编译》中了解到了它们各有什么优点和缺点,以及前端编译+JIT编译方式的运作过程。 下面我们...
  • 利用wsdl文件生成webservice接口java客户端测试代码
  • 编译java文件的时候会发现一个java文件可以生成的多个class文件,而且有的还含有“$”符号,这个符号代表的是内部类,举个例子: public class ClassA { private class ClassB { private void show() { System....
  • java生成api接口文档

    千次阅读 2019-09-20 15:35:56
    API接口文档,对于Java开发团队来说,是必不可少的一项工作,不管是JSP展示,前后端分离,还是前后端的代码在一个项目中,都是写展示页面必须参考的文档之一。生成接口文档一般有两种方法: 1、手写,费时费力; 2...
  • public class Stu{ interface A { void onTouch(); } public ...javac编译之后生成 ...可以看出总共生成了三个class文件。为接口A生成了一个class文件,为内部类生成了一个Stu$1.class文件
  • 主要是动态编译这点比较有趣, 1 定义一个接口,只有一个方法,sell (为什么要定义这个接口,就不多说了..面向接口编程可以说是必须的) package com.cjb.proxy; /**  * 类说明  * 表示商店  * @creator  ...
  • 利用编译时注解生成Java源代码

    千次阅读 2016-11-09 15:48:49
    编译时注解开发
  • 之前需要调后台接口中的方法,向后台人员咨询,丢给我一个idl文件,刚拿到不知道怎么搞,经过查找资料,原来这个idl文件是可以转成java代码的,然后导入到项目中编译。那怎么才能把idl文件java代码呢?我的方法是...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...
  • 首先说推荐的好用的工具JD,基本语法都正常,而且保留了编译后的那些内部类,方法,这匿名类方法具体我下面会说。但是有些语法糖,尤其是for循环反编译后结果有些乱,他总是把for循环的变量做成全局变量,这种时候该...
  • 本以为重启服务会重新编译产生class文件覆盖,所以就没在意 而后导致了之前的接口能访问,新写的接口不能访问(报404), 后来找到原因是target里面没有生成对应的class 下面左图中controller 中又Band1...
  • 1.Java保存的文件名必须与类名一致; 2.如果文件中只有一个类,文件名必须与类名一致;... 当编写一个Java源代码文件时,此文件通常被称为编译单元(有时也称为转译单元)。每个编译单元都必须要有一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 239,777
精华内容 95,910
关键字:

java接口编译后生成的文件

java 订阅