Replacing/Overriding Java "native" Classes? - java

I'm working with BigDecimals and I have the requirement that a division by 0 should not result in an ArithmeticException, but in returning 0 instead (weird business math).
This is a rather new requirement and we already have quite a bit of code, which uses BigDecimals in a lot of places. I don't want to go through all these places and implement zero checks. This also would not help me with 3rd party libraries, which might internally use BigDecimals and will throw an ArithmeticExceptioninstead.
I'd also like to set a default precision/scale and change the compareTo method to able to ignore small rounding errors.
Because of all these global changes which would create a lot of "boilerplate" code, I came up with the idea to change the implementation of BigDecimal. I've already done this before for other 3rd party classes to fix certain bugs myself.
I replaced those classes by creating a class with the same name in the same package like the 3rd party class, and because the external jar files will be loaded after my own classes, I was able to replace them.
But creating a java.math.BigDecimal didn't help me, because it seems that the "native" Java classes are loaded even before my own classes.
Let's assume that I really want every single BigDecimal in my application to work a bit different, how would I be able to replace the "official" BigDecimal? Am I allowed to do that, and could there be some other, technical problems I didn't think of now?

You have to put your classes in the "bootstrap" classpath if you want to override builtin classes. as to the wisdom of actually doing this (i.e. your changes will affect the entire jvm)...

BigDecimal is not final, so you could definitely extend it yourself, and change its behaviour (especially by overriding the divideXXX() methods).
You won't have to change the parameters etc., but remember to change the type of actually used objects! So you will use "your" methods.
As to compareTo() etc. you also won't have any problems - BigDecimal itself implements Comparable interface and has its own compareTo().

Related

How should Number be extended for classes without a no-args constructor?

I have implemented a few Java classes which extend the abstract java.lang.Number class. I have no immediate need for serializing objects of these classes. However, I do want to provide the rest of the Number contract for these classes which represent "numbers." The trouble is that java.lang.Number implements Serializable. As such, my classes are supposed to provide public default (i.e. no-args) constructors -- my IDE complains, but the compiler will still compile my classes. Fine, but providing public default constructors for "immutable" objects requires providing a default value when the constructor is invoked for any reason other than serialization -- ignore for the moment that these classes return objects from static factory methods and expose no public constructors now. Well, zero is a fine default in many cases, but natural numbers -- i.e. positive integers -- do not include zero in their domain and no single number is any more "special" than any other...O.K...."one" is always "special"...
Etc., etc., etc....
I did look into how BigDecimal handles Number and Serializable in an effort to determine the "right" way to address this question. However, both the JavaDoc and the source code I have been able to examine reveals BigDecimal does not provide a "no-args" constructor despite having extended Number. Realizing that:
Just because Sun Microsystems/Oracle implemented it that way doesn't make it "right."
I am back to the basic question:
What is the "right" way to extend java.lang.Number? If providing a "no-args" constructor is just another Java convention following the rule:
It's not a law, just a good idea...
Is the best answer to avoid the warts by ignoring the "convention?" If so, how can I satisfy an IDE -- Intellij, in particular -- and any Java-to-other-language-or-environment translator which might choose to be more strict than the Java compiler when Serializable raises its ugly head?
Well, there's always good ol 'NaN' -- Not a number. If you can represent it, that is.
My opinion is that one could forget about being compatible with Java's built-in serialization after looking at the benchmarks. It's 8x slower than textual Jackson and seems being just outdated.
You can also make the empty constructor protected, this way serialization still works. What Sun did for BigDecimal was providing readObject and writeObject methods , see here for further details.

JVM bytecode limitations on class-class interactions

I was looking through the JVM bytecode instructions and was surprised to see that all the interactions between classes (e.g. casting, new, etc.) rely upon constant pool lookups for identity of the other classes.
Am I correct in inferring that this means that one class cannot know about the existence of more than 64k others, as it is impossible to refer to them? If one did need to refer to that many, what ought one do--delegate the work to multiple classes each of which could have their own <64k interactions?
(The reason this interests me is that I have a habit of writing code generators, sometimes producing thousands of distinct classes, and that some languages (e.g. Scala) create classes prolifically. So it seems that if true I have to be careful: if I have hundreds of methods in a class each using hundreds of (distinct) classes, I could exceed the constant pool space.)
Am I correct in inferring that this means that one class cannot know about the existence of more than 64k others, as it is impossible to refer to them?
I think you are correct. And don't forget that there are constant pool entries for other things; e.g. all of the classes method and fields names, and all of its literal strings.
If one did need to refer to that many, what ought one do--delegate the work to multiple classes each of which could have their own <64k interactions?
I guess so.
However, I'm not convinced that this concern would ever be realized in practice. It is hard to conceive of a class that needs to directly interact with that many other classes ... unless the code generator is ignoring the structure of its input source code.
It sounds like your problem could be solved via invokedynamic. This is basically a much faster form of reflection designed to ease the implementation of dynamic languages on the JVM.
If you really do have to deal with thousands of automatically generated classes, you probably don't want to statically link it all. Just use invokedynamic. This also has the advantage of letting you defer some code generation to runtime.
Note that you still need a constant pool entry for every dynamic method called by a class, but you no longer need to refer to the actual class and methods being called. In fact, you can create them on demand.

JAVA bytecode optimization

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.
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.

Where to put potentially re-useable helper functions?

This is language agnostic, but I'm working with Java currently.
I have a class Odp that does stuff. It has two private helper methods, one of which determines the max value in an int[][], and the other returns the occurrences of a character in a String.
These aren't directly related to the task at hand, and seem like they could be reused in future projects. Where is the best place to put this code?
Make it public -- bad, because Odp's functionality is not directly related, and these private methods are an implementation detail that don't need to be in the public interface.
Move them to a different class -- but what would this class be called? MiscFunctionsWithNoOtherHome? There's no unifying theme to them.
Leave it private and copy/paste into other classes if necessary -- BAD
What else could I do?
Here's one solution:
Move the method that determines te max value in a two-dimensional int array to a public class called IntUtils and put the class to a util package.
Put the method that returns the occurrences of a character in a String to a puclic class called StringUtils and put the class to a util package.
There's nothing particularly bad about writing static helper classes in Java. But make sure that you don't reinvent the wheel; the methods that you just described might already be in some OS library, like Jakarta Commons.
Wait until you need it!
Your classes wil be better for it, as you have no idea for now how your exact future needs will be.
When you are ready, in Eclipse "Extract Method".
EDIT: I have found that test driven development give code that is easier to reuse because you think of the API up front.
A lot of people create a Utility class with a lot of such methods declared as static. Some people don't like this approach but I think it strikes a balance between design, code reuse, and practicality.
If it were me, I'd either:
create one or more Helper classes that contained the methods as static publics, naming them as precisely as possible, or
if these methods are all going to be used by classes of basically the same type, I'd create an abstract base class that includes these as protected methods.
Most of the time I end up going with 1, although the helper methods I write are usually a little more specific than the ones you've mentioned, so it's easier to come up with a class name.
I not know what the other languages do but I have the voice of experience in Java on this: Just move to the end-brace of your class and write what you need ( or nested class if you prefer as that is accepted canonical convention in Java )
Move the file scope class ( default access class right there in the file ) to it's own compilation unit ( public class in it's own file ) when the compiler moans about it.
See other's comments about nested classes of same name if differing classes have the same functionality in nested class of same name. What will happen on larger code bases is the two will diverge over time and create maintainability issues that yield to Java's Name of class as type of class typing convention that forces you to resolve the issue somehow.
What else could I do?
Be careful not to yield to beginner impulses on this. Your 1-2 punch nails it, resist temptation.
In my experience, most large projects will have some files for "general" functions, which are usually all sorts of helper functions like this one which don't have any builtin language library.
In your case, I'd create a new folder (new package for Java) called "General", then create a file to group together functions (for Java, this will just be a class with lots of static members).
For example, in your case, I'd have something like: General/ArrayUtils.java, and in that I'd throw your function and any other function you need.
Don't worry that for now this is making a new class (and package) for only one function. Like you said in the question, this will be something you'll use for the next project, and the next. Over time, this "General" package will start to grow all sorts of really great helper classes, like MathUtils, StringUtils, etc. which you can easily copy to every project you work on.
You should avoid helper classes if you can, since it creates redundant dependencies. Instead, if the classes using the helper methods are of the same type (as kbrasee wrote), create an abstract superclass containing the methods.
If you do choose to make a separate class do consider making it package local, or at least the methods, since it may not make sense for smaller projects. If your helper methods are something you will use between projects, then a library-like approach is the nicest to code in, as mentioned by Edan Maor.
You could make a separate project called utils or something, where you add the classes needed, and attach them as a library to the project you are working on. Then you can easily make inter-project library updates/fixes by one modification. You could make a package for these tools, even though they may not be that unified (java.util anyone?).
Option 2 is probably your best bet in Java, despite being unsatisfying. Java is unsatisfying, so no surprise there.
Another option might be to use the C Preprocessor as a part of your build process. You could put some private static functions into file with no class, and then include that file somewhere inside a class you want to use it in. This may have an effect on the size of your class files if you go overboard with it, of course.

Inject New Methods and Properties into Classes During Runtime

Is there any way we can inject new methods and properties into classes during run-time.
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html states we may do that by using Groovy.
Is it possible by just doing using Java?
Is it possible by just doing using
Java?
The simple answer is an emphatic "You don't want to do that!".
It is technically possible, but not without resorting to extremely complex, expensive and fragile tricks like bytecode modification1. And even then, you have to rely on dynamic loading to access the modified type and (probably) reflection to make use of its new members. In short, you would be creating lots of pain for yourself, for little if any gain.
Java is a statically typed language, and adding / modifying class type signatures can break the static typing contract of a class.
1 - AspectJ and the like allow you to inject additional behaviour into a class, but it is probably not the "runtime" injection that you are after. Certainly, the injected methods won't be available for statically compiled code to call.
So if you were really crazy, you could do something like what they outline here. What you could do is load the .java file, find the correct insertion point, add whatever methods you need to, call the java compiler and reload the class. Good luck debugging that mess though :)
Edit This actually might be of some use...
You can do some quite funky things with AOP, although genuine modification of classes at runtime is a pretty hairy technique that needs a lot of classloading magic and sleight of hand.
What is easier is using AOP techniques to generate a subclass of your target class and to introduce new methods into this instead, what AOP called a "mixin" or "introduction". See here to read how Spring AOP does it, although this may be quite lame compared to what you're actually trying to achieve.
Is it possible by just doing using Java?
Quite so, the "only" thing you have to do is define an instrumentation agent which supplies an appropriate ClassFileTransformer, and you'll have to use reflection to invoke the added methods. Odds are this isn't what you want to do, though, but it's doable and there's a well-defined interface for it. If you want to modify existing methods you may be interested in something like AspectJ.
While it might be possible, it is not useful.
How would you access these new fields and methods?
You could not use these methods and fields directly (as "ordinary" fields and methods), since they wouldn't be compiled in.
If all you want is the possibility to add "properties" and "methods", you can use a Map<String, Object> for the "dynamic properties", and a Map<String, SuitableInterface> for the "dynamic methods", and look them up by name.
If you need an extension language for Java, an embedded dynamic language (such as Javascript, or Groovy) can be added; most of these can access arbitrary java objects and methods.

Categories