2

Imagine the following situation:
1. Consume a 3rd party WSDL, out comes thousands of classes.
2. There's an opportunity to optimize performance by using a custom paralleled implementation.
3. Wsdl class structure has consistent naming convention: [RecordType][CrudAction]
4. Use Java Reflection to create type-less functions taking advantage of naming convention patterns
5. Result would reduce all possible implementations of wsdl class base by a factor of what would otherwise be needed to iterate through all [RecordTypes] and [CrudAction] possibilities. P = A * B becomes P = A + B

I've read several sources that it's bad to use reflection, or that it has a very specific type of problem. Was Java Reflection intended to solve for this type of problem? FWIW, this feels like a hacky aspect-oriented programming solution to help scale interfacing to a large 3rd party class base. The Spring framework is also available, however, this could help lower overhead.

7
  • Basically what it comes down to here is that you are asking if it's a good idea to generate a ton of statically defined classes and then use them a way that ignores static type definitions. What goal does generating the classes further?
    – JimmyJames
    Commented Apr 8, 2019 at 15:32
  • Because statically typed objects is still a benefit to type-safety, and junior programmers tend to like to have typed objects because, well, that's what they were taught in school. Also, this approach allows for a looser coupling than say... a giant switch case addressing each type? Would be nice if could some how inject an interface to objects I don't have control. Like, if the object in reference had the same function signatures, then program to the interface and not the type. Keep in mind the reflection idea is only being used in this narrow case. Commented Apr 9, 2019 at 11:01
  • How can generating a classes that are isomorphic to thousands of types in a schema be loose coupling? A switch statement (while nothing really wrong with it for the right situation) is not really needed here. Likely you want a pattern matching solution. Doing this with DOM is going to look extremely similar to reflecting against generated types. The type generation is just an unnecessary complication. This is a common pattern: Step 1. generate classes from a schema. Step 2. figure out what you are trying to accomplish.
    – JimmyJames
    Commented Apr 10, 2019 at 13:42
  • "Because statically typed objects is still a benefit to type-safety" You realize that is not the case when you use reflection right? Reflection completely side-steps type safety.
    – JimmyJames
    Commented Apr 10, 2019 at 17:04
  • In this case, reflection will only be used by one developer within the team, and will encapsulated away from the other developers. The other developers will be using the objects as intended, and not with reflection. This is what I mean that there will still be a benefit of type safety. As for the loose coupling comment, I'm not sure what defines as "loose coupling", but in relative terms, dynamically invoking method based on a given object type is looser than statically calling the same semantic method for every object combination. Commented Apr 10, 2019 at 20:04

2 Answers 2

8

There are two fundamental things about reflection that can make it bad.

  • Reflection can break protections like private.
  • Reflection can cause performance problems.

These perfectly valid concerns are used by some shops as excuses to swear off ever using reflection. This is wrong. Reflection is a powerful tool that should be used wisely.

For example, a class that has been carefully designed to create immutable objects can be quietly defeated with reflection. This makes reasoning about how the code behaves difficult. When you know there is no reflection used in the code base you can look at only the class to know that it is immutable. Once reflection is on the table you have to read all the code in the code base to know how immutable it is.

You must weigh all that against the benefit you're going to get by using reflection to help you consume this WSDL. Following such rules makes reasoning about the code easier.

My advice: use it narrowly. Create an isolated space to use it where it's walled off from the rest of your code, and forbid its use where you don't have a real good need for it. If someone suspects reflection is causing an object to behave oddly, don't make their effort to find the cause an epic journey through the code base. Make it obvious where the problem is.

As for performance, there are real issues but mostly I've been surprised how fast aspect oriented solutions are. Don't let fear keep you from trying ideas. Get a profiler to tell you where your real problems are.

Of course the real problem of using reflection here is it gives you the power to consume a WSDL so poorly designed that you need these kinds of shenanigans to consume it. But how else are you going to let your foot shoot it self in the foot?

4
  • 2
    Upvote for "use it narrowly, create an isolated space to use it where it's walled off from the rest of your code, and forbid its use where you don't have a real good need for it." Reflection in this case serves a very practical purpose, so use it. Just don't make it your "go-to" solution for everything.
    – Neil
    Commented Apr 8, 2019 at 8:04
  • 1
    The other 'bad' thing about reflection is it defeats a lot of the value of using a statically-typed language. For example, when you do something like 'show references', you never can be sure it's giving you the full picture.
    – JimmyJames
    Commented Apr 8, 2019 at 15:26
  • 1
    While it is possible to bypass access controls with Java reflection it is not the default behaviour. It's perfectly reasonable to allow reflection while banning the use of "setAccessible(true)". Commented Apr 8, 2019 at 16:04
  • You missed the 3rd fundamental thing: It ends up in spaghetti-code impossible to read.
    – Laiv
    Commented Apr 8, 2019 at 19:26
1

Basically what it comes down to here is that you are asking is it's a good idea to generate a ton of statically defined classes and then use reflection to avoid referencing them in a static way. Assuming there's no other reason you need these class definitions, it's not clear why you would want to generate classes in the first place.

If you want to work with XML using dynamic approaches, there are a number ways to accomplish that in Java. Here are three:

  • DOM - Easy to understand. Heavy memory footprint and a little sluggish
  • SAX - Very fast and low memory requirements. A little awkward for a lot of Java developers
  • Stax - A balance between usability and efficiency.

There's no requirement that you map XML structures to types. And even if you do want to, there's nothing that requires you to make your structures one-to-one with the XML schema. For example, if you want to map a lot of schema-types to a single Java type based on a reliable naming convention and consistent structure, SAX could be a great choice for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.