Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access to class' Fields without using reflection?

Is there a way to access a specific Field on a class without using reflection?

Consider this class:

class MyType {
    public int theNumber;
}

Where I would like to get access to theNumber's java.lang.reflect.Field.

This works for sure:

Field f = MyType.class.getDeclaredField("theNumber");

However, I would like compile check on the field name, so ideally something like this instead (but of course my example doesn't compile):

Field f = MyType.class::theNumber;

Is this possible or am I way of wrt the compiler abilities?

like image 603
Geir Avatar asked Sep 09 '15 09:09

Geir


People also ask

What can I use instead of reflection in Java?

The alternate for reflection is using Interface. Just taking from Effective Java by Joshua Bloch. We can obtain many of the benefits of reflection while incurring few of its costs by using it only in a very limited form.

How do you access a private field that is a member of a class?

If we want to access Private Field and method using Reflection we just need to call setAccessible(true) on the field or method object which you want to access. Class. getDeclaredField(String fieldName) or Class. getDeclaredFields() can be used to get private fields.

Is getClass reflection?

getClass() is reflection per se since it can be used to examine the given object.

How do you get a class field?

The getField() method of java. lang. Class class is used to get the specified field of this class, which is the field that is public and its members. The method returns the specified field of this class in the form of Field objects.


2 Answers

You can extend the java compiler with annotation processors. This processors are a way to scan your source code during compile. They were introduced with Annotations but they are able to scan the whole source code not only annotations.

With the scanned Source-Code you can generate accessor classes to any class you compile. This way you can eliminate reflection.

If you only want to get errors while you write code in your IDE you can make use of javax.annotation.processing.ProcessingEnvironment.getMessager().printMessage() (see also javax.tools.DiagnosticListener) to generate Errors the IDE can show.

So the basic Idea is:

  1. write an annotation processor which scans the source code you want to reflect
  2. extract the field you want to have access to via javax.lang.model.element.ElementVisitor

In case you want to generate type save access to Field:

3.1. generate source that will access this source code

In case you want to ensure, that a reflective call to a field is valid:

3.2. raise an Error via ProcessingEnvironment.getMessager().printMessage()

Of course you have to write the code for checking reflective calls or generating the accessors.

And the information you want to get must be extractable from the sourcecode since all the magic happens during the compile and not at runtime

like image 71
truthslie Avatar answered Sep 30 '22 18:09

truthslie


Interesting question. No, there's no way to do that without using java.lang.reflect, but given the built-in class pseudo-property on classes, I can see why you'd ask.

like image 20
T.J. Crowder Avatar answered Sep 30 '22 18:09

T.J. Crowder