Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java reflection appropriateness

This may be a fairly subjective question, but maybe not. My application contains a bunch of forms that are displayed to the user at different times. Each form is a class of its own. Typically the user clicks a button, which launches a new form.

I have a convenience function that builds these buttons, you call it like this:

buildButton( "button text", new SelectionAdapter() {
     @Override
     public void widgetSelected( SelectionEvent e ) {
        showForm( new TasksForm( args... ) );
     }
  } );

I do this dozens of times, and it's really cumbersome having to make a SelectionAdapter every time.

Really all I need for the button to know is what class to instantiate when it's clicked and what arguments to give the constructor, so I built a function that I call like this instead:

buildButton( "button text", TasksForm.class, args... );

Where args is an arbitrary list of objects that you could use to instantiate TasksForm normally.

It uses reflection to get a constructor from the class, match the argument list, and build an instance when it needs to. Most of the time I don't have to pass any arguments to the constructor at all. The downside is obviously that if I'm passing a bad set of arguments, it can't detect that at compilation time, so if it fails, a dialog is displayed at runtime. But it won't normally fail, and it'll be easy to debug if it does.

I think this is much cleaner because I come from languages where the use of function and class literals is pretty common. But if you're a normal Java programmer, would seeing this freak you out, or would you appreciate not having to scan a zillion SelectionAdapters?

like image 615
jsn Avatar asked Oct 15 '22 05:10

jsn


2 Answers

Yeah, usually reflection is frowned upon but in some cases it can be quite useful. I would appreciate reading code which i can digest fairly quickly without having to go through a zillion little thingies.

like image 175
JHollanti Avatar answered Oct 18 '22 14:10

JHollanti


If I understand correctly, you want to execute one operation (createButton) with different kinds of button implementations (forms) for argument. This sounds exactly like you need polymorphism.

I suggest you forget about reflection and construct these forms under a common interface. Let's say interface Form { //some methods here }

All your forms will have to implement the common interface and these methods are required for the creation of the button. So if you have a Form object, you can pass it to the createButton(Form formObject){...}

IF all SelectionAdapter does is call a showForm method, you can add it to the common interface Form and just invoke this method for a Form object. Thus you don't need to create many anonymous classes but just one and instantiating it with a "Form" object.

So all you need is polymorphism and nicely chosen interfaces for these classes.

If you have a big problem with creating the Form objects (their constructors differ), may be you should consider creating a MyFormBuilder which handles construction only. The builder will have createInstance() method or getInstance() method which will do all the work.

With my suggestion you will have 1 SelectionAdapter class implementation, you will be passing objects with common interface and will have avoided reflection, passing MyClass.class arguments and so on.

like image 44
Leni Kirilov Avatar answered Oct 18 '22 13:10

Leni Kirilov