Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
反编译器工具在java中修改.class文件的源代码_Java_Compiler Optimization_Decompiler_.class File - Fatal编程技术网

反编译器工具在java中修改.class文件的源代码

反编译器工具在java中修改.class文件的源代码,java,compiler-optimization,decompiler,.class-file,Java,Compiler Optimization,Decompiler,.class File,我使用djjava反编译工具从JAVA中的类文件中获取源代码。它生成的源文件的代码与我之前在原始源程序中编写的代码不同 我的疑问是: 这是因为JVM在创建 目标代码可提高执行速度并减少空间和时间 复杂性 或者反编译器工具修改.class文件代码以生成 又是源程序 见原始源程序如下: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLExc

我使用djjava反编译工具从JAVA中的类文件中获取源代码。它生成的源文件的代码与我之前在原始源程序中编写的代码不同

我的疑问是:

  • 这是因为JVM在创建 目标代码可提高执行速度并减少空间和时间 复杂性
  • 或者反编译器工具修改.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编译器实际上不优化生成的代码(尽管有一些优化,比如计算常量表达式和内联某些静态final字段)

    但问题是,实际上,您不能期望返回您开始使用的确切代码。Java不是脚本语言,代码实际上被编译成字节码——原始文本源代码不存储在类文件中的任何位置

    您发布的输出与您可能期望的一样好。如果类文件中根本没有存储诸如空格、注释和格式之类的内容,那么您总是会丢失这些内容。对于底部的循环,显然有多种方法可以编写相同的代码,而反编译器只是选择了一种不同的方式来表达相同的代码。由于无法判断最初使用的是所有可能的等效代码样式中的哪一种,反编译器只能猜测


    这可能只是一种启发式的结果,人们通常为循环编写代码,而不是像您最初那样为循环编写代码。在这种特殊情况下,没有人会将print语句放在这样的for循环表达式中,但启发法不可能是完美的。

    Java编译器只做最少量的优化

    大多数优化仅由JIT编译器完成(因为它拥有关于平台和运行时环境的最多信息)

    for循环和while循环在字节码中使用相同的模式。这并不奇怪,因为所有while循环都可以作为相同的for循环轻松地重新编写


    由于在字节码版本中,for循环和while循环看起来相同,反编译器可能会将其反编译为while循环。

    您能解释一下您观察到的任何更改吗?因此,为了优化目的,编译器会对其进行编译。如果将源代码中的for循环与反编译版本中的while循环进行比较,就可以得出这个想法。在我使用while循环的原始源代码中。后来在反编译之后,我看到while循环被for循环所取代,代码仍然运行良好。你解释的没错,但仍然不满意。你能解释一下生成的for循环吗?@choxx如果你仔细观察for循环,你会发现它和while循环做的事情是一样的。for循环中的语句通常只是用来增加一个变量,但并没有说它们必须这样做。我只是想知道反编译器工具是如何开发出这样的内部逻辑的,代码转换就是以这种方式进行的。那真是太好了@choxx您必须询问JAD(DJ使用的引擎)的开发人员。这可能很难,因为JAD太老了。