1

This is a basic question.

I have code which shouldn't run on metadata beans. All metadata beans are located under metadata package.

Now,

I use reflection API to find out whether a class is located in the the metadata package.

if (newEntity.getClass().getPackage().getName().contains("metadata")) 

I use this If in several places within this code.

The question is: Should I do this once with:

boolean isMetadata = false
if (newEntity.getClass().getPackage().getName().contains("metadata")) {
   isMetadata = true;
}

C++ makes optimizations and knows that this code was already called and it won't call it again. Does JAVA makes optimization? I know reflection API is a beat heavy and I prefer not to lose expensive runtime.

2
  • 1
    The correct approach is to: (1) choose whatever option you think leads to the clearest and least error-prone code; (2) use a profiler to find the actual performance bottlenecks; (3) optimize those. Commented Nov 25, 2012 at 10:34
  • 2
    Using the package name as a flag in your program doesn't sound like very good design. I'm not sure what you're doing but there a probably better/simplier ways to achieve it Commented Nov 25, 2012 at 10:38

1 Answer 1

6

You should of course check whether there really is a performance issue before putting any work into optimising. getClass() is probably quite fast already (faster than instanceof, anyway). You could probably cache the set of classes that are in the metadata package so you don't need to keep checking the package names.

If you really need to compare packages, you could find the metadata package once, using the Package.getPackage(String name) method, then for each object, call getClass().getPackage() as before, and compare the two package objects.

This is quicker and more elegant than checking for a string in the package name, but would probably not work correctly if there are multiple classloaders, as the Package objects wouldn't be equal (==) and Package doesn't over-ride .equals(). Thinking about it, it may not even be guaranteed to work on a single classloader, but I suspect that in practice you get the same Package instance rather than another copy - would be wise to check this first!, e.g:

String.class.getPackage() == Integer.class.getPackage() // should be true

Update if you check the source code for Class.getPackage(), Package.getPackage() and ClassLoader.getPackage() you can see that they cache the Package objects, so you should be safe comparing them when using a single classloader

One problem of a package-naming convention is that you have to enforce and maintain it throughout the codebase, which could become a maintenance problem over time. A more explicit way of identifying the classes might be better.

Alternative approaches to identify specific groups of classes include:

  • Making your metadata beans implement a marker interface
  • Using Java Annotations to mark metadata beans
  • Making all beans implement a common interface with a method that can be called to check whether the are in a specific category that you define. This is ugly as it's basically duplicating the type system, but would be fast since it doesn't need reflection.
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.