java编译与反编译 - Go语言中文社区

java编译与反编译


1、编译和反编译

Java的编译分为两个阶段,首先,源代码经过词法分析,语法分析直至语义分析,然后就会产生一个class文件,这段过程称之为前端编译,此时产生的class文件还无法被计算机识别执行,只能算是整个编译过程中产生的一个中间产物。然后JVM将读取到的二进制文件进行深度编译,将其编译成与具体平台相关的指令代码,这个过程是后端编译,它主要依赖于JVM。

前端编译是与操作系统平台无关的,最终生成的class文件是可以在各个JVM平台进行深度编译;而后端编译就需要跟具体操作系统平台相关了,因为JVM有不同平台的版本,可以将这种统一格式的class文件进一步深度编译,将其转换成与具体平台相关的指令代码。

编译
对于编译器,Java内置的有javac工具,此外很多IDE工具也内置了编译工具,但是这些都是前端编译器,主要功能就是把【.java】文件编程成【.class】文件。

反编译
将编译后的class文件转换成最初编写的源代码的形式,这个过程就是反编译。
javap是JDK自带的一个反编译工具,反编译后的不是java文件。
也可以直接把class文件拖到IDE工具内打开(反编译),展示形式不一样。

2、编译有依赖,无法通过

idea新建项目test,在包名example.demo.reflect下有两个java文件,Parent和Son,Son继承自Parent。

进入E:ideaprojecttestsrcexampledemoreflect目录下,javac Parent.java 是OK的。javac Son.java报错。

E:ideaprojecttestsrcexampledemoreflectParent.java
E:ideaprojecttestsrcexampledemoreflectSon.java

Parent.java

package example.demo.reflect;
public class Parent {
}

Son.java

package example.demo.reflect;
public class Son extends Parent {
}

试验一:

直接进入reflect文件夹下面,javac Son.java,报错找不到符号
在这里插入图片描述

2.1、解决方案一:

  • 先定位到src路径下,再编译
  • javac example/demo/reflect/Son.java
    在这里插入图片描述

2.2、解决方案二:

  • 指定cp 为 src路径
  • -cp <路径> 指定查找用户类文件和注释处理程序的位置
    在这里插入图片描述

同理,如果编译一个RSA.java文件,但其中依赖Base64.java文件,Base64位于 android.util.Base64中
定位到Base64.jar包所在的文件位置(C:Userszhenzhen.xieAppDataLocalAndroidSdkplatformsandroid-29/android.jar)

javac -encoding utf8 -cp C:Userszhenzhen.xieAppDataLocalAndroidSdkplatformsandroid-29/android.jar RSA.java

2.3、javac编译之后的class文件

Parent.class

package example.demo.reflect;
public class Parent {
    public Parent() { 
    } //系统会给一个默认的无参构造函数,如果已经指定构造函数,则不会生成这个默认的
}

Son.class

package example.demo.reflect;
public class Son extends Parent {
    public Son() {
    }//系统会给一个默认的无参构造函数,如果已经指定构造函数,则不会生成这个默认的
}

原理

  • java 为了防止类冲突,引入命名空间 nameSpace,和系统文件路径保持一致。

  • pakage 表示类在哪个路径包下;

  • import 表示引入哪个路径包下的内容;

  • 我们的Son和Parent文件的包名是example.demo.reflect,也就是说起始点是E:ideaprojecttestsrc,src路径下

  • 而利用javac进行编译时,默认情况下的类搜索路径为当前路径。

  • 试验一:在reflect路径下,编译Son,Son需要先定位Parent,根据Parent的包名,在当前路径(E:ideaprojecttestsrcexampledemoreflect)下找不到example/demo/reflect/Parent.java。

  • 试验二:通过文本编辑器将 Son 和 Parent 的第一行pakage去掉,在reflect路径下,编译Son.java,是Ok的

  • 解决方案一:在src路径下,根路径下,根据包名example.demo.reflect,可以定位到Son,也可以定位到Parent

  • 解决方案二:虽然是在reflect路径下,通过cp指定查找用户类文件的路径E:ideaprojecttestsrc,则刚好可以和Parent的包名组成一个有效路径。E:ideaprojecttestsrcexampledemoreflectParent.java

注:
编码GBK的不可映射字符
javac -encoding utf-8 xxx.java 即可
在这里插入图片描述

参考:
Java中的编译与反编译
关于Javac命令和类文件之间的依赖问题

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/ZHENZHEN9310/article/details/90037552
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-04-12 05:41:13
  • 阅读 ( 673 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢