I theoretically understand the point why there is no abstract static in Java, as explained for instance in Why can't static methods be abstract in
annotations could be fine for your purpose.
@FileProperties(desc="data file")
public class DataFile extends XFile { ... }
FileProperties props = DataFile.class.getAnnotation(FileProperties.class);
String desc = props.desc();
Accessing the info still requires reflection, however it's a little better than using static field/method.
Java compiler does not enforce that all subclasses are annotated as such. You can add your logic to the compiler (using annotation processing) but that's too complicated. It's ok to check it at runtime.
Update:
This is also possible:
@FileInfoClass ( DataFileInfo.class )
@public class DataFile