简体   繁体   中英

Decompiler tools modify the source code for .class file in java

I used DJ JAVA DECOMPILER tool to get back the source code from .class file in java. What the source file it generated was having different code than what i coded earlier in the original source program .

What my doubt is:

  1. Is this because of JVM does code optimization before creating the target code for better execution speed & reduce space and time complexity?
  2. Or the decompiler tool modify the .class file code to generate the source program again?

See the original source program was this:

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));
        }


    }
}

After decompilation what i got is:

// 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)));
    }
}

The Java compiler does virtually no optimization of the code produced (though there is a little, like evaluating constant expressions and inlining certain static final fields).

The thing though is that you can't realistically expect to get back the exact code you started with. Java is not a scripting language, and the code is actually compiled into bytecode - the original textual source code is not stored anywhere in the classfiles.

The output you posted is as good as you can possibly expect. You're always going to lose stuff like whitespace, comments, and formatting given that that's not stored at all in the classfile. For the loop at the bottom, there are obviously multiple ways to write the same code, and the decompiler just chose a different way of expressing the same code. Since there is no way to tell which of all the possible equivalent code styles was originally used, the decompiler just guesses.

It's probably just the result of a heuristic that people more commonly write for loops than while loops like you originally had. In this particular case, noone would actually put print statements in a for loop expression like that, but heuristics can't be perfect.

Java Compiler does only, minimal set of optimization.

Most optimization is done by JIT compiler only.(Since it has the most information about the Platform and runtime environment.)

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

Since in bytecode version,, the for loop and while loop looks same, the decompiler might decompile it into while loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM