Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java/Scala obtain a Field reference in a typesafe way

Java claims to be object oriented and typesafe, and Scala even more so.

Internal Class fields are represented by class called Field, which you can obtain a reference to via the Reflection API.

My question: do these languages provide any way to obtain that Field reference in a typesafe way? (And if not, why on earth not? Seems like a glaring deficiency)

It would be extremely useful when mapping an Object to some external representation, for example to html fields in a template, or to column names in a database, to keep the reference names automatically in sync.

Ideally I'd like to say something like:

&(SomeClass.someField).name() 

to get the name of the field declaration, similar to how java enums let you say:

MyEnum.SOME_INSTANCE.name()

[update:] after reading feedback that this functionality would somehow violate the intent of the Reflection API, I agree that Reflection is designed for things that aren't known at compile time, and that's exactly why it's so absurd to have to use it to learn things that are known at compile time, namely the Fields of the very class that it's compiling!

The compiler provides this for enums, so if the compiler is able to access the enum Field's reference to allow MyEnum.SOME_INSTANCE.name(), then there's no logical reason why it shouldn't also be able to provide this same functionality to ordinary Classes.

Is there any technological reason why this functionality couldn't be there for ordinary classes? I don't see why not, and I disagree that this functionality would "complicate" things... on the contrary it would vastly simplify the present cumbersome Reflection API techniques. Why force developers into Reflection to find out something that is known at compile time?

[update #2] as for the utility of this feature, have you ever tried using the Criteria API in JPA or Hibernate to dynamically construct a query? Have you seen the absurd work-arounds people have come up with to try to avoid having to pass in an unsafe String representation of the field to query against?

[update #3] Finally, a new JVM language called Ceylon has heeded the call and makes this trivial to do!

like image 902
Magnus Avatar asked Mar 24 '12 21:03

Magnus


2 Answers

My question: do these languages provide any way to obtain that Field reference in a typesafe way?

Compile-time typesafe? Not that I'm aware of, at least in Java. The normal purpose of reflection in Java is for code to be able to deal with types it has no knowledge of before-hand - it's rare (in my experience) to be in a position where you want to be able to refer to a field in a known type. It does happen, but it's not very common.

(And if not, why on earth not? Seems like a glaring deficiency)

Every feature needs to be designed, implemented, tested, and has to meet the balance of providing more value than the added complexity in the language.

Personally I can think of features I'd much rather see in Java than this.

like image 78
Jon Skeet Avatar answered Nov 15 '22 13:11

Jon Skeet


It is a pity that Java still misses this feature. This feature would not add additional complexity because it would interfere with other aspects of the language. Furthermore, being a feature that would be rarely used is not excuse. Every language is full of features and most projects make use of a small subset of them.

I really don't understand why the language allows me to do this:

Field field = MyClass.class.getField("myField"); // verbose syntax, evaluate at runtime, not type-safe, must deal with Reflective operation exceptions

But it doesn't let me do (something like) this:

Field field = MyClass::myField; // compact syntax, evaluated at compile-time, type-safe, no exceptions!

(the "::" operator is just a suggestion, borrowed from java 8 or c++)

like image 25
Giannis Avatar answered Nov 15 '22 15:11

Giannis