Skip to content

Instantly share code, notes, and snippets.

@FLamparski
Created September 19, 2015 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FLamparski/a6ba7bce1f758dcf98cd to your computer and use it in GitHub Desktop.
Save FLamparski/a6ba7bce1f758dcf98cd to your computer and use it in GitHub Desktop.
"Partial classes" in Java

Compiling and running

$ cpp -ansi Main.partial.java | sed 's|^#|//|' > Main.java
$ javac Main.java
$ java Main
Magic!

But... C preprocessor only works on C?!

Not true. From the manpage of GNU cpp 4.9.2:

The C preprocessor is intended to be used only with C, C++, and Objective-C source code. In the past, it has been abused as a general text processor. It will choke on input which does not obey C's lexical rules. For example, apostrophes will be interpreted as the beginning of character constants, and cause errors. Also, you cannot rely on it preserving characteristics of the input which are not significant to C-family languages. If a Makefile is preprocessed, all the hard tabs will be removed, and the Makefile will not work.

Having said that, you can often get away with using cpp on things which are not C. Other Algol-ish programming languages are often safe (Pascal, Ada, etc.) So is assembly, with caution.

Well, Java is sufficiently C-like for CPP to not throw up on simple files.

Sed?! WTF?

Output from raw cpp:

# 1 "Main.partial.java"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "Main.partial.java"
public class Fuck {
# 1 "main2.java" 1
  public static void frobozz() {
    System.out.println("Magic!");
  }
# 3 "Main.partial.java" 2

  public static void main(String[] args) {
    frobozz();
  }
}

Useful for the C compiler, but will mess up javac. So we turn all lines that start with a # and nothing else into comments.

Super hacky, why would I do that?!

You probably shouldn't. But you can. A "real" use case would be something like keeping autogenerated Java from, say, a graphical form designer and your application logic separate like C# did since the beginning, but then why not use something that lets you define your layouts in XML?

public class Main {
#include "main2.java"
public static void main(String[] args) {
frobozz();
}
}
public static void frobozz() {
System.out.println("Magic!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment