反编译器工具修改 java 中 .class 文件的源代码
Decompiler tools modify the source code for .class file in java
我使用 DJ JAVA DECOMPILER 工具从 取回 源代码。[= java 中的 40=] 文件。它生成的源文件与我之前在原始源程序.
中编写的代码不同的代码
我的疑问是:
- 这是不是因为JVM在创建之前做了代码优化
目标代码以获得更好的执行速度并减少 space 和时间
复杂度?
- 或者反编译工具修改.class文件代码生成
又是源程序?
看到原来的源程序是这样的:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class Test1 {
/**
* @param args
* @throws SQLException
* @throws ClassNotFoundException
*/
public static void main(String args[]) throws SQLException, ClassNotFoundException{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:choxx","choxx","choxx");
if(con==null){
System.out.println("not established");
}else{
System.out.println("established");
}
Statement st= con.createStatement();
//st.executeQuery("create table student if not exists(sno number(10), name varchar2(30), addr varchar(20))");
if(st!=null){
System.out.println("table created..");
}
st.execute("delete from student where addr='hyderabad'");
ResultSet rs= st.executeQuery("select * from student");
while(rs.next()){
System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getString(3));
}
}
}
反编译后得到的是:
// Decompiled by DJ v3.12.12.99 Copyright 2015 Atanas Neshkov Date: 29-03-2015 10:55:31
// Home Page: http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: Test1.java
import java.io.PrintStream;
import java.sql.*;
public class Test1
{
public Test1()
{
}
public static void main(String args[])
throws SQLException, ClassNotFoundException
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:choxx", "choxx", "choxx");
if(con == null)
System.out.println("not established");
else
System.out.println("established");
Statement st = con.createStatement();
if(st != null)
System.out.println("table created..");
st.execute("delete from student where addr='hyderabad'");
for(ResultSet rs = st.executeQuery("select * from student"); rs.next(); System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3)));
}
}
Java 编译器几乎没有对生成的代码进行优化(尽管有一些优化,例如评估常量表达式和内联某些静态最终字段)。
尽管如此,您实际上不能指望取回您开始使用的确切代码。 Java 不是脚本语言,代码实际上被编译成字节码——原始文本源代码没有存储在类文件中的任何地方。
您发布的输出与您预期的一样好。你总是会丢失诸如空格、注释和格式之类的东西,因为它们根本没有存储在类文件中。对于最底层的循环,同样的代码显然有多种写法,反编译器只是选择了不同的表达方式来表达同样的代码。由于无法判断最初使用了所有可能的等效代码样式中的哪一个,因此反编译器只是猜测。
这可能只是一种启发式的结果,人们更常编写 for 循环,而不是像您最初使用的 while 循环。在这种特殊情况下,实际上没有人会像那样将 print 语句放在 for 循环表达式中,但启发式方法并不完美。
Java 编译器只进行最少的优化。
大多数优化仅由 JIT 编译器完成。(因为它具有最多的有关平台和运行时环境的信息。)
for-loops and while-loops use an identical pattern in byte code. This is not surprising because all while-loops can be re-written easily as an identical for-loop
http://blog.jamesdbloom.com/JavaCodeToByteCode_PartOne.html
由于在字节码版本中,for循环和while循环看起来一样,反编译器可能会将其反编译为while循环。
我使用 DJ JAVA DECOMPILER 工具从 取回 源代码。[= java 中的 40=] 文件。它生成的源文件与我之前在原始源程序.
中编写的代码不同的代码我的疑问是:
- 这是不是因为JVM在创建之前做了代码优化 目标代码以获得更好的执行速度并减少 space 和时间 复杂度?
- 或者反编译工具修改.class文件代码生成 又是源程序?
看到原来的源程序是这样的:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class Test1 {
/**
* @param args
* @throws SQLException
* @throws ClassNotFoundException
*/
public static void main(String args[]) throws SQLException, ClassNotFoundException{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:choxx","choxx","choxx");
if(con==null){
System.out.println("not established");
}else{
System.out.println("established");
}
Statement st= con.createStatement();
//st.executeQuery("create table student if not exists(sno number(10), name varchar2(30), addr varchar(20))");
if(st!=null){
System.out.println("table created..");
}
st.execute("delete from student where addr='hyderabad'");
ResultSet rs= st.executeQuery("select * from student");
while(rs.next()){
System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getString(3));
}
}
}
反编译后得到的是:
// Decompiled by DJ v3.12.12.99 Copyright 2015 Atanas Neshkov Date: 29-03-2015 10:55:31
// Home Page: http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: Test1.java
import java.io.PrintStream;
import java.sql.*;
public class Test1
{
public Test1()
{
}
public static void main(String args[])
throws SQLException, ClassNotFoundException
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:choxx", "choxx", "choxx");
if(con == null)
System.out.println("not established");
else
System.out.println("established");
Statement st = con.createStatement();
if(st != null)
System.out.println("table created..");
st.execute("delete from student where addr='hyderabad'");
for(ResultSet rs = st.executeQuery("select * from student"); rs.next(); System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3)));
}
}
Java 编译器几乎没有对生成的代码进行优化(尽管有一些优化,例如评估常量表达式和内联某些静态最终字段)。
尽管如此,您实际上不能指望取回您开始使用的确切代码。 Java 不是脚本语言,代码实际上被编译成字节码——原始文本源代码没有存储在类文件中的任何地方。
您发布的输出与您预期的一样好。你总是会丢失诸如空格、注释和格式之类的东西,因为它们根本没有存储在类文件中。对于最底层的循环,同样的代码显然有多种写法,反编译器只是选择了不同的表达方式来表达同样的代码。由于无法判断最初使用了所有可能的等效代码样式中的哪一个,因此反编译器只是猜测。
这可能只是一种启发式的结果,人们更常编写 for 循环,而不是像您最初使用的 while 循环。在这种特殊情况下,实际上没有人会像那样将 print 语句放在 for 循环表达式中,但启发式方法并不完美。
Java 编译器只进行最少的优化。
大多数优化仅由 JIT 编译器完成。(因为它具有最多的有关平台和运行时环境的信息。)
for-loops and while-loops use an identical pattern in byte code. This is not surprising because all while-loops can be re-written easily as an identical for-loop
http://blog.jamesdbloom.com/JavaCodeToByteCode_PartOne.html
由于在字节码版本中,for循环和while循环看起来一样,反编译器可能会将其反编译为while循环。