What I’m trying to achieve is a nice abstraction for my database tables. The result I’m looking for is to be able to do this:
System.out.println(Table.Appointment); // prints the name of the table
System.out.println(Table.Appointment.ID); // prints the name of the column
Here is what I’ve come close with, but fields seem to take priority over static inner classes.
public class Table {
// attempt to allow 'Table.Appointment' to resolve to a String
public static final Table Appointment = new Table("Appointment");
// attempt to give access to column names within the table,
// these class names should be the same as its name field above.
public static final class Appointment{
public static final String ID = "AppointmentId";
};
private String name;
private Table(String name){ this.name = name; }
public String toString() { return name; }
}
Can this actually be achieved?
While I strongly discourage what you are doing, simply because it makes your application too solid, this works (Edited to avoid cyclic references.) :
This is as close as you can get from what you want. Note that users won’t actually see this design, only programmers will… so who cares?
Also, having access to
Table.AppointmentTableis normal. This is how you can accessTable.Appointment.ID. But you can’t create an instance of it neither extend it, and it is all good.** Edit **
Why this limitation? Because you can’t just use a type and treat it as a value. A type defines the container, not the content. And as much as you can’t
System.out.println(int);becauseintis a token (or a type, or a container), you cannot treat a class name as a value that you can echo. Among other things, this is why you haveTable.AppointmentTable.class.getSimpleName()(or.getName()).You can only work with values. A class definition is not a value, it’s a definition of a container for a value. The variable of that class definition hold the content of that container, from which you can echo or manipulate.
The same thing goes with unassigned variables. If you try :
the compiler will whine about
foonot being initialized. This is because declaring a variable does not assign any content to it (you declare a container of typeintnamedfoo), does not make it hold any content unless you assign something (contents) to it.