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:\ideaproject\test\src\example\demo\reflect目录下,javac Parent.java 是OK的。javac Son.java报错。

E:\ideaproject\test\src\example\demo\reflect\Parent.java
E:\ideaproject\test\src\example\demo\reflect\Son.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:\Users\zhenzhen.xie\AppData\Local\Android\Sdk\platforms\android-29/android.jar)

javac -encoding utf8 -cp C:\Users\zhenzhen.xie\AppData\Local\Android\Sdk\platforms\android-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:\ideaproject\test\src,src路径下

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

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值