Getting Method objects without reflection

M

mark

This is a shameless plug to try to get votes for a recent bug I've
filed:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6356762

For a long time, it's bothered me that there is no way other than
reflection to obtain Method and Field objects to identify components of
classes. It should be possible to write something like
MyClass::nameOfMyField to obtain the FIeld object directly. With the
current reflection-only method, one has to obtain these by looking up
their String names. So:

-there's no way for the compiler to detect syntax errors at compile
time
-no real way to obfuscate this code
-debugging is more difficult because you are working indirectly through
strings
-it's inelegant to use Strings to perform at runtime what the compiler
should be able to do at compile time

One of the most immediate uses for this could be with classes
conforming to the Beans pattern. Instead of specifying String names
directly when firing property change events (whilch always risks a typo
cauing a hard to trace error), you could obtain the coresponding Field
object and call getName() on it.

If something like this could be provided in Mustang, I would be in
seventh heaven. Please vote for the bug, or let me know what you think
about this.
 
H

hilz

This is a shameless plug to try to get votes for a recent bug I've
filed:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6356762

For a long time, it's bothered me that there is no way other than
reflection to obtain Method and Field objects to identify components of
classes. It should be possible to write something like
MyClass::nameOfMyField to obtain the FIeld object directly. With the
current reflection-only method, one has to obtain these by looking up
their String names. So:

-there's no way for the compiler to detect syntax errors at compile
time


If you know the method or filed's name at compile time, why would you
need reflection or some other way? you can just call the method directly
or access the filed directly. I doubt what you're asking for has any
real value. (just my thought).
 
M

mark

Sometimes you need to deal with methods and fields in teh abstract.
For example, when you fire a property change event, you are effectively
passing the field you modifed in the event you create.

If you do any work with the reflection API, this would become quite
handy. Just because you can call a method directly in one part of a
program does not mean that another part can.
 
C

Chris Smith

This is a shameless plug to try to get votes for a recent bug I've
filed:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6356762

Seems reasonable, in any case. I don't see a decent syntax that would
work for it, and that's my biggest concern. That, and the possibility
that someone who is working on this could have been doing something
useful; but I've never bought that argument anywhere else, so why now?
One of the most immediate uses for this could be with classes
conforming to the Beans pattern. Instead of specifying String names
directly when firing property change events (whilch always risks a typo
cauing a hard to trace error), you could obtain the coresponding Field
object and call getName() on it.

No, this is not a valid use. JavaBeans properties are a concept that is
independent from fields. I can write this bean:

public class MyBean
{
private int index;
private List<String> names;

public String getName()
{
return names.get(index);
}

public void setName(String name)
{
names.add(name);
index = names.size() - 1;
}
}

What Field object are you going to attach to a property change event
when the "name" property changes in that bean? This may seem silly, but
it's not. Plenty of more complex beans have properties that aren't
bound 1-to-1 with fields; it's just hard to provide a simple example
without going into a lot of complex background about why property values
are interdependent.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

If you do any work with the reflection API, this would become quite
handy. Just because you can call a method directly in one part of a
program does not mean that another part can.

Absolutely. hilz' question is exactly analogous to the question of why
we have the Something.class syntax. Your answer is right.

Another part of the answer, though, is that very shallow reflection
involving java.lang.Class is widely useful and quite common. It makes
sense to provide a syntax to deal with it. Reflection that involves
Method or Field objects is of the uber-dynamic kind. The need for your
new field/method literal expressions could be seen as a very good
indicator of misusing reflection.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
M

mark

While one is not obliged to use getters and setters that corespond to
field names when creating bean properties, very often one does. When
one does, being able to obtain the name of the field directly is an
advantage, since it lets the compiler do the syntax checking for you.

A better example would be when you're creating your own custom events
to fire. You may know that an event coresponds to a particular method
of field, and want to include that in your event. Messing with Strings
instead would mae your code less accurate and more difficult to track
down syntax errors with spelling.

And also, methods and fields can be obfuscated while strings cannot.
So being able to call getName() on a Field has a big security advantage
over using raw reflection.
 
C

Chris Uppal

And also, methods and fields can be obfuscated while strings cannot.
So being able to call getName() on a Field has a big security advantage
over using raw reflection.

Since this feature -- if it were added -- would certainly be implemented by the
compiler generating traditional (string-based) reflective code under-the-hood,
I don't think that it would permit more thorough obfuscation that is currently
possible.

Personally, I can see some motivation for this, but I think it provides too
little benefit to justify the cost in complexity (for me, the programmer,
having to learn and use an even /more/ grossly over-complicated language) nor
in development costs (/every/ tool which is Java source-code aware -- e.g..
Eclipse -- would have to be updated).

BTW, the syntax you propose would not work for reflective access to either
constructors or fields, and that -- IMO -- is a big negative point.

-- chris
 
C

Chris Smith

While one is not obliged to use getters and setters that corespond to
field names when creating bean properties, very often one does. When
one does, being able to obtain the name of the field directly is an
advantage, since it lets the compiler do the syntax checking for you.

Sure, it's true 95% of the time. In order to modify the JavaBeans event
mechanism, though, it would have to be true 100% of the time, with no
acceptions.

If you're talking about something like (making up an unworkable syntax):

String fieldName = FIELD(MyClass.theField).getName();

and then continuing to use a String for the JavaBeans event, then that's
fine... just so long as you don't propose changing JavaBeans to require
a Field object for all property change events.
A better example would be when you're creating your own custom events
to fire. You may know that an event coresponds to a particular method
of field, and want to include that in your event. Messing with Strings
instead would mae your code less accurate and more difficult to track
down syntax errors with spelling.

Okay.

Although... I am getting a little concerned that you seem to think this
syntax should break encapsulation. You've never quite said so, but it
seems to be just below the surface. It would be a grave mistake to
create such a syntax which could break encapsulation. Far better to
have nothing at all.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Chris Uppal said:
Since this feature -- if it were added -- would certainly be implemented by the
compiler generating traditional (string-based) reflective code under-the-hood,
I don't think that it would permit more thorough obfuscation that is currently
possible.

Certainly, this would be the case initially. Eventually, though, it
would gain its own bytecode mechanisms, much like class literals.
BTW, the syntax you propose would not work for [...]

There are certainly many things wrong with the syntax. Certainly they
could be solved, though. It will be a challenge to find something
sensible that is usable for overloaded methods/constructors, though. Is
that what you meant to say?

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Uppal

Chris said:
Certainly, this would be the case initially. Eventually, though, it
would gain its own bytecode mechanisms, much like class literals.

Maybe... I assume you mean that the ldc instruction could be extended (again)
to accept the index of a Methodfef_Info, Fieldref_Info, or Interfaceref_info.
I don't think it could possibly be worth the JVM changes myself (but then I
think Sun were stupid to make JVM changes for class literals).

BTW, the syntax you propose would not work for [...]

There are certainly many things wrong with the syntax. Certainly they
could be solved, though. It will be a challenge to find something
sensible that is usable for overloaded methods/constructors, though. Is
that what you meant to say?

No. I agree that it would be a challenge to create a syntax which would
distinguish between overloaded members (especially members overloaded only on
[return-]type ;-). But in fact all I had in mind was that the proposed syntax
(just drop the (...) bit to get the "method" without calling it) would not work
for fields (obviously) or constructors.

Incidentally, another problem that would have to be sorted out is what
expressions like

Method m = "a string".notifyAll;

(using the OP's syntax) would mean. Would they be permitted or not ? Would
the compiler be required to recognise that String didn't override notifyAll()
and convert the reference into a reference to the method object for
Object.notifyAll() ? Or would it be required to follow the pattern established
by method invocation where the compiler is required to generate code referring
to String.notifyAll() (as described in the binary compatibility stuff). Does
the fact that Object.notifyAll() is declared final affect this issue ? Not
questions that are impossible to answer, but questions that would have to /be/
answered...

-- chris
 
R

ricky.clarkson

I'll freely admit that I haven't read much of the above, so here's an
uneducated gut reaction:

A PropertyChangeEvent should refer to a Property. A Field is not a
Property.

Java would need some form of property syntax/annotation for this to be
possible sensibly.

It might be possible to statically do something like this with Java as
it is, using the apt tool.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,244
Latest member
cryptotaxsoftware12

Latest Threads

Top