Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
111 views
in Technique[技术] by (71.8m points)

java - Programs that reproduces itself

Is it possible to make a Java program that prints its source code to a new file, and compiles it, and runs the compiled program?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Update:

Okay, might as well make it autorun. Enjoy the madness. Run at your own risk.


Yes it's possible, because I actually wrote it up. It doesn't do the RUN part (that's just too crazy, because as others have mentioned, it will cause an infinite loop), but here it is: Quine.java

import java.io.*;
public class Quine {
   public static void main(String[] args) throws Exception {
      char q = 34;
      String out = "Quine$";
      String text = (
         "import java.io.*; " +
         "public class [OUT] { " +
           "public static void main(String[] args) throws Exception { " +
             "char q = 34; String out = `[OUT]$`; String text = `[TEXT]`; " +
             "PrintWriter pw = new PrintWriter(out + `.java`); " +
             "pw.format(text, 34, out, text); " +
             "pw.close(); Runtime runtime = Runtime.getRuntime(); " +
             "runtime.exec(`javac ` + out + `.java`).waitFor(); " +
             "runtime.exec(`java ` + out); " +
           "} " +
         "}"
      ).replace("`", "%1$c").replace("[OUT]", "%2$s").replace("[TEXT]", "%3$s");
      PrintWriter pw = new PrintWriter(out + ".java");
      pw.format(text, 34, out, text);
      pw.close();
      Runtime runtime = Runtime.getRuntime();
      runtime.exec("javac " + out + ".java").waitFor();
      runtime.exec("java " + out);
   }
}

So here's how to get the craziness to start:

  • javac Quine.java to compile
  • java Quine to run it
    • It will produce, compile and run Quine$
  • I've made sure Quine.java is as readable as possible, so the major difference from Quine$.java are formatting and the 3x replace. The minor difference is that Quine$.java has out set to Quine$$.
  • Quine$ will produce, compile and run Quine$$
  • Quine$$ will produce, compile and run Quine$$$
  • Quine$$$ will produce, compile and run Quine$$$$
  • ...

Do note that this doesn't do any reverse-engineering or cheat by reading the .java source code, etc. Quine is a quine-generator because it produces a different code differently formatted, but Quine$ is pretty much a true self-contained quine: it does reproduce itself, it just relabels it Quine$$ (which reproduces itself and relabels to Quine$$$ etc).

So technically there's no infinite loop: it will eventually come to a halt when the file system can't handle another $. I was able to manually stop the madness by forcefully deleting all Quine$* files, but run at your own risk!!!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...