Passing a class as argument to a method, then calling static methods - java

I have a use case with a class existing in 2 versions of a package.
package packageV1;
public class MyClass extends BaseClass{
public static String example(){
return "Version1";
}
}
package packageV2;
public class MyClass extends BaseClass{
public static String example(){
return "Version2";
}
}
So far so good (I believe).
Then I have an application using that class, and to avoid rewriting the application for the different package version, I want to pass the class that should be use (ie for the package of interest) as argument to the application.
So something like
public class Application{
private Class<BaseClass> selectedClass;
public void Application(Class<BaseClass> selectedClass){
this.selectedClass = selectedClass;
this.selectedClass.example(); // not possible
}
}
I believe I could call this.selectedClass.example(); if I were passing an instance of MyClass in the constructor, but then I would call static methods through a instance object, not nice right ?
On the other hand, in the example above selectedClass is a Class object, so I can't call the static method example as above.
Does this mean I should use reflection ? like selectedClass.getMethod(name, parameterTypes).
Looks overly complicated to me.
Or is there a better design ?

#javadev is right. Using reflection is almost always a really bad idea. It is that which over complicates.
There is no need for reflection here. The ability to invoke static methods on instances was rapidly realised to be a design error. So much so that there is a subsequent highly unorthogonal design choice in that it does not work for static methods that are members of interfaces.
The simple solution is to move the static methods to instance methods of stateless objects. No Class, or other reflection, necessary. This is an application of the Strategy design pattern.

Using a static method this way is not a good design, and not according to the Object Orinted principles.
My tip is to try changing "example()" to be a regular method, and not static.

Related

Cleanest way to wrap Java static methods in a non-static object (refactoring to allow mocking)

I'm working with Java and Kotlin, and the codebase has some legacy static logic which really should be in objects, but is too deeply tangled to make non-static now. I want to be able to cleanly test (using mocks of these static dependencies) some (non-static) classes that depend on this static logic, so I want to wrap the static logic classes in non-static dummy wrappers, i.e. instantiatable objects whose instance methods just call their static counterparts. I'll then mock these wrappers in unit tests (I don't want to just use static mocking).
The manual way to do this is for each static logic class Foo with method public static void bar(), define a new class FooWrapper with method public void bar() that just calls Foo.bar(), instantiate a FooWrapper at the top of my class, and switch all the current calls to Foo.bar() to instead call fooWrapperInstance.bar().
The above works fine but involves a lot of boring Wrapper classes that do nothing but pass calls. Is there some syntactic sugar (either Java or Kotlin is fine, but it has to work with Java) that will create, or at least shorten, these wrapper classes for me? I'm familiar with Guava's ForwardingObject but it seems to only work when the underlying logic is in an instance already, which mine is not.
The shortest way to write your wrappers would be to use the method references as follows.
Say you have this Java class
public class A {
static String hello() {
return "";
}
}
Then you want to create a wrapper for it in Kotlin like this
class AKotlin {
val hello = A::hello
}
Now AKotlin::hello will have the same signature as the static A::hello method, but will be an object method instead

Why have public static class inside a class

I was going through some code and I saw this:
public class A {
public A(SomeObject obj) {
//Do something
}
//Some stuff
public static class B {
//Some other stuff
}
}
I was wondering since even the inner class is public why have it as nested and not a separate class?
Also, can I do this here: new A.B(SomeObject) ? I feel this defeats the purpose of a static class but I saw this implementation as well so wanted to know.
I was wondering since even the inner class is public why have it as nested and not a separate class?
That's really a matter to ask whoever wrote the class. It can allow the outer class to act as a "mini-namespace" though - if the nested class is only useful in the context of the outer class, it seems reasonable. It indicates deliberate tight coupling between the two classes. I most often see this in the context of the builder pattern:
Foo foo = new Foo.Builder().setBar(10).build();
Here it makes sense to me to have Foo.Builder nested within Foo rather than as a peer class which would presumably be called FooBuilder.
Note that it also gives some visibility differences compared with just unrelated classes.
Also, can I do this here: new A.B(SomeObject) ?
No, because B doesn't have a constructor with a SomeObject parameter - only A does (in the example you've given).
I feel this defeats the purpose of a static class
You should try to work out exactly what you deem the purpose of a static class to be, and in what way this defeats that purpose. Currently that's too vague a statement to be realistically discussed.
You would have an inner class like this so
you can keep an class which only exists to support the outer class encapsulated.
you want to be able to access private members of the outer class or other nested classes.
you want a nested class with static fields (a weak reason I know ;)
you have a class with a very generic name like Lock or Sync which you wouldn't want to be mixed with other classes of the same name used by classes in the same package.
can I do this here: new A.B(SomeObject) ?
You can.
I feel this defeats the purpose of a static class
It takes getting used to but once you start you may have trouble not turning your entire program into one file.java ;)
1. A static inner class is known as Top-Level Class.
2. This static class has direct access to the Its Outer class Static method and variables.
3. You will need to initialize the static Inner class in this way from Outside...
A a = new A();
A.B b = new A.B();
4. new A.B(SomeObject) won't work... because you don't have a constructor with SomeObject as parameter...
5. But when the Inner class is Non-static, then it have implicit reference to the Outer class.
6. The outer and inner class can extends to different classes.
7. An interface's method can be implemented more than once in different or same ways, using Inner Class.
This pattern is used very often with the builder pattern. It not only makes clear the relation between a class and its builder, but also hides the ugly builder constructor/factory and makes builder more readable. For example in case you need your built object to have optional and not optional properties.
public class AnObject {
public static class AnObjectBuilder {
private AnObject anObject;
private AnObjectBuilder() {
}
private void newAnObjectWithMandatory(String someMandatoryField, ...) {
anObject = new AnObject(someMandatoryField,...)
}
public AnObjectBuilder withSomeOptionalField(String opt) {
...
}
}
public static AnObjectBuilder fooObject() {
return (new AnObjectBuilder()).newAnObjectWithMandatory("foo")
}
public static AnObjectBuilder barObject() {
return (new AnObjectBuilder()).newAnObjectWithMandatory("bar")
}
}
This way the client code have to call first the static method on the AnObjectBuilder class and then to use the optional builder methods:
AnObject.fooObject("foo").withSomeOptionalField("xxx").build(); without creating the builder object.
Pretty readable :)
I was wondering since even the inner class is public why have it as nested and not a separate class?
Have a look at this thread: Why strange naming convention of "AlertDialog.Builder" instead of "AlertDialogBuilder" in Android
Also, can I do this here: new A.B(SomeObject) ?
(Update) No, you can't do this, since B doesn't have a constructor that asks for SomeObject.
I hope this helps.
I was wondering since even the inner class is public why have it as
nested and not a separate class?
The simple reason it is allowed is packaging convenience.
Static nested class in Java, why?
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
yes, you can do new A.B(SomeObject). But you don't have to take my word for it, try it out.

Java final abstract class

I have a quite simple question:
I want to have a Java Class, which provides one public static method, which does something. This is just for encapsulating purposes (to have everything important within one separate class)...
This class should neither be instantiated, nor being extended. That made me write:
final abstract class MyClass {
static void myMethod() {
...
}
... // More private methods and fields...
}
(though I knew, it is forbidden).
I also know, that I can make this class solely final and override the standard constructor while making it private.
But this seems to me more like a "Workaround" and SHOULD more likely be done by final abstract class...
And I hate workarounds. So just for my own interest: Is there another, better way?
You can't get much simpler than using an enum with no instances.
public enum MyLib {;
public static void myHelperMethod() { }
}
This class is final, with explicitly no instances and a private constructor.
This is detected by the compiler rather than as a runtime error. (unlike throwing an exception)
Reference: Effective Java 2nd Edition Item 4 "Enforce noninstantiability with a private constructor"
public final class MyClass { //final not required but clearly states intention
//private default constructor ==> can't be instantiated
//side effect: class is final because it can't be subclassed:
//super() can't be called from subclasses
private MyClass() {
throw new AssertionError()
}
//...
public static void doSomething() {}
}
No, what you should do is create a private empty constructor that throws an exception in it's body. Java is an Object-Oriented language and a class that is never to be instantiated is itself a work-around! :)
final class MyLib{
private MyLib(){
throw new IllegalStateException( "Do not instantiate this class." );
}
// static methods go here
}
No, abstract classes are meant to be extended. Use private constructor, it is not a workaround - it is the way to do it!
Declare the constructor of the class to be private. That ensure noninstantiability and prevents subclassing.
The suggestions of assylias (all Java versions) and Peter Lawrey (>= Java5) are the standard way to go in this case.
However I'd like to bring to your attention that preventing a extension of a static utility class is a very final decision that may come to haunt you later, when you find that you have related functionality in a different project and you'd in fact want to extend it.
I suggest the following:
public abstract MyClass {
protected MyClass() {
}
abstract void noInstancesPlease();
void myMethod() {
...
}
... // More private methods and fields...
}
This goes against established practice since it allows extension of the class when needed, it still prevents accidental instantiation (you can't even create an anonymous subclass instance without getting a very clear compiler error).
It always pisses me that the JDK's utility classes (eg. java.util.Arrays) were in fact made final. If you want to have you own Arrays class with methods for lets say comparison, you can't, you have to make a separate class. This will distribute functionality that (IMO) belongs together and should be available through one class. That leaves you either with wildly distributed utility methods, or you'd have to duplicate every one of the methods to your own class.
I recommend to never make such utility classes final. The advantages do not outweight the disadvantages in my opinion.
You can't mark a class as both abstract and final. They have nearly opposite
meanings. An abstract class must be subclassed, whereas a final class must not be
subclassed. If you see this combination of abstract and final modifiers, used for a class or method declaration, the code will not compile.
This is very simple explanation in plain English.An abstract class cannot be instantiated and can only be extended.A final class cannot be extended.Now if you create an abstract class as a final class, how do you think you're gonna ever use that class, and what is,in reality, the rationale to put yourself in such a trap in the first place?
Check this Reference Site..
Not possible. An abstract class without being inherited is of no use and hence will result in compile time error.
Thanks..

How to run the method from final class with private constructor?

How to run the method foo() in class A without any changes on this class
public final class A{
private A(){
System.exit(0);
}
public void foo(){
System.out.println("from foo");
}
}
Without doing something like using reflection or bytecode manipulation to mess with accessibility...
The "right" way to do this is to get an instance of the class some other way. For example, if there's a static factory method or pre-made instances that you can access. The reason for having a private constructor like this is to control construction of the class. (For example, enum implementations have a private constructor so that you don't create additional instances beyond the static ones supplied.)
If you side-step this then someone (either you or the original class author) is doing something wrong.
You can create an instance of a class without calling the constructor. See this question: Is it possible to create an instance of an object in Java without calling the constructor?
You can use objenesis to do this for you. Once you've got an instance of A without calling the constructor, calling foo is easy.
You can alter the byte code before it is loaded by the jvm. Here's a place to start:
http://www.ibm.com/developerworks/java/library/j-dyn0916/index.html

Should Helper/Utility Classes be abstract?

I commonly find myself extracting common behavior out of classes into helper/utility classes that contain nothing but a set of static methods. I've often wondered if I should be declaring these classes as abstract, since I can't really think of a valid reason to ever instantiate these?
What would the Pros and Cons be to declaring such a class as abstract.
public [abstract] class Utilities{
public static String getSomeData(){
return "someData";
}
public static void doSomethingToObject(Object arg0){
}
}
You could just declare a private constructor that does nothing.
The problem with declaring the class "abstract" is that the abstract keyword usually means that class is intended to be subclassed and extended. That's definitely not what you want here.
Don't bother making them abstract, but include a private parameterless constructor to prevent them from ever being instantiated.
Point of comparison for those interested: in C# you would declare the class to be static, making it abstract and sealed (Java's final) in the compiled form, and without any instance constructor at all. That also makes it a compile-time error to declare a parameter, variable, array etc of that type. Handy.
I don't declare utility classes abstract, I declare them final and make the constructor private. That way they can't be subclassed and they can't be instantiated.
public final class Utility
{
private Utility(){}
public static void doSomethingUseful()
{
...
}
}
I would add more step beyond the private constructor:
public class Foo {
// non-instantiable class
private Foo() { throw new AssertionError(); }
}
Throwing the AssertionError prevents methods in the same class from instantiating the class (well, they can try). This isn't normally a problem but in a team environment you never know what someone will do.
As regards the "abstract" keyword, I have noticed utilities classes subclassed in numerous instances:
public class CoreUtils { ... }
public class WebUtils extends CoreUtils { ... }
public class Foo { ... WebUtils.someMethodInCoreUtils() ... }
I believe this is done so that people don't have to remember which utility class to include. Are there any downsides to this? Is this an anti-pattern?
Regards,
LES
By declaring them as abstract, you are in effect indicating to other coders that you intended for these classes to be derived from. Really, you're right, that there's not much difference, but the semantics here are really more about the interpretation of other people who look at your code.
As others stated, make a private parameter-less constructor. No-one can create an instance of it, apart from the class itself.
As others have shown how it is done with other languages, here comes how you do it in the next C++ version, how to make a class non-instantiable:
struct Utility {
static void doSomething() { /* ... */ }
Utility() = delete;
};
I think it's better to declare utility classes final with a private no-args constructor. Moreover all members of this class should be static.
An easy way to do all this in one statement is to use the #UtilityClass annotation of Lombok:
#UtilityClass
public class Utilities{
public String getSomeData() {
return "someData";
}
public void doSomethingToObject(Object arg0) {
}
}
If you use the #UtilityClass annotation you can skip the static keywords as in the example above since Lombok adds them automatically during compilation.
No, but if your language supports it, there's a strong argument to be made that in most cases they should (can) be declared as 'static'... Static tells the compiler that they cannot be instantiated, and that all methods in them must be static.
Abstract is for classes that DO have instance-based implementation details, which WILL be used by instances of derived classes...
someone mentioned that in C# 3.0 you could accomplish this via extension methods. I'm not a C# guy, did some back in the 1.5/2.0 days, but have not used it since then. Based on a very cursory understanding I think something similar can be accomplished in java with static imports. I realize its not at all the same thing, but if the goal is to just make these utility methods seem a bit more "native"(for lack of a better term) to the calling class, I think it will do the trick. Assuming the Utilities class I declared in my original question.
import static Utilities.getSomeData;
public class Consumer {
public void doSomething(){
String data = getSomeData();
}
}
Might I offer some constructive advice?
If you are doing a lot of this, there are two problems you will run into.
First of all, a static method that takes a parameter should often be a part of the object that is that parameter. I realize this doesn't help for objects like String, but if it takes objects you've defined, you could almost certainly improve the object by including your helper as a method of that object.
If it takes all native values, you probably could define an object that it's a method of. See if you can find any grouping of those native values and group them as an object. If you just try that, you'll find a lot of other uses for that little mini-object, and before you know it it will be amazingly useful.
Another thing, if you have a utility class with a bunch of semi-related static methods and static variables, you almost always want it to be a singleton. I found this out by trial and error, but when you find out you need more than 1 (eventually you will), it's MUCH easier to make a singleton into a multipleton(?) then to try to change a static class into a multipleton(okay, so I'm making words up now).
Good luck. This stuff was mostly trial and error for me--figured it out like 5 years ago though, and I've never found an instance where I regretted not having static class/methods.
Helper / Utility methods are just fine. Don't worry about adding them to a library inside your application or Framework. Most frameworks that I have seen use them in many varieties.
That being said, if you want to get really crafty about them you should look into extension methods in C# 3.0. Using extension method will make your Utilities a little more of a "holistic" part of your framework which it seems like what you're trying to do by considering to make them abstract. Not to mention extension method are a lot of fun to write!

Categories