How to Avoid Constructor calling During Object Creation? - java

I want to avoid the constructor calling during object creation in java (either default constructor or user defined constructor) . Is it possible to avoid constructor calling during object creation???
Thanks in advance......

Simply extract the intialization logic that you want to avoid into another method called init. You can not avoid calling exactly one constructor.

No matter what pattern or strategy you use, at some point your will need to call a constructor if you want to create an object.

Actually, its possible under some circumstances by using classes from the JVM implementation (which do not belong to the JRE API and are implemenation specific).
One example here http://www.javaspecialists.eu/archive/Issue175.html
It should also be possible using sun.misc.Unsafe.allocateInstance() (Java7)
Also, the constructor is apparently bypassed when using the clone()-method to create a copy of an object (and the class doesn't override clone to implement it different from the Object.clone() method).
All of these possibilities come with strings attached and should be used carefully, if at all.

You can mock the constructors of a class. They will still be called, but not executed. For example, the following JUnit+JMockit test does that:
static class CodeUnderTest
{
private final SomeDependency someDep = new SomeDependency(123, "abc");
int doSomething(String s)
{
someDep.doSomethingElse(s);
return someDep.getValue();
}
}
static final class SomeDependency
{
SomeDependency(int i, String s) { throw new RuntimeException("won't run"); }
int getValue() { return -1; }
}
#Test
public void mockEntireClassIncludingItsConstructors()
{
new NonStrictExpectations() {
#Mocked SomeDependency mockDep;
{ mockDep.getValue(); result = 123; }
};
int result = new CodeUnderTest().doSomething("testing");
assertEquals(123, result);
}

Related

How to pass a method as an argument to a different method?

I have a method let's say in ClassA. I want to pass a method from ClassB as an argument to that method in ClassA. In this case I want to pass the getCode method from ClassB. I don't have any instance of ClassB and I'd like to achieve this without having to create one.
I've tried using simple method reference, but it does not work this way.
I don't want to make getCode a static method either.
public class ClassA {
public void validate() {
Validation validation = new Validation(ClassB::getCode, code);
//...
}
}
My final goal is to have a RequestValidator class to which add validations, each validation will be created with a specific method and a string in its constructor, in this case getCode from classB and code. Please note I only want one instance of RequestValidator. Something like this:
RequestValidator validator = new RequestValidator<>()
.addValidation(new Validation(ClassB::getCode, code))
.addValidation(new Validation(ClassB::getName, name));
getCode needs to be a static function, and the syntax would be ClassB.getCode. You would need ClassB to be imported into ClassA.
See:
Calling static method from another java class
Your use of a method reference will work just fine as long as you define the method arguments properly. You haven't given a lot of information, so I'm going to make some assumptions here. Please correct me if this isn't what you had in mind:
public class B {
public static String getCode() {
return "foobar"; // Replace with your own functionality
}
}
public class Validation {
Validation(Supplier<String> supplier, String code) {
String suppliedCode = supplier.get();
// Do your validation logic
}
}
public static void validate() {
Validation validation = new Validation(ClassB::getCode, code);
}
But this frankly feels like overkill. Why can't you just make your Validation constructor take two String arguments (or whatever types you happen to be using), and then do this?
public static void validate() {
Validation validation = new Validation(ClassB.getCode(), code);
}
Do you have a legitimate need to pass in a method reference instead of simply passing in the return value from the method call?

Test a method without initialize the class

I'm very new to unit testing, I'm wondering if there is a way to test a method without initializing the class. The reason I'm asking is because there are lot of object passing in the constructor meaning a lot of mocking stubbing while from a thorough check methodToTest seems not to use any object attribute. It's not my code otherwise the method could be converted to static.
class ExampleClass {
public ExampleClass(FirstClass fc, SecondClass sc, ThirdClass tc) {}
public void methodToTest(FourthClass foc) {}
}
You have some options here:
Make the method static so you don't need a reference to an actual object. This will only work if the method does not need any state of ExampleClass (i.e. everything it needs is passed in the method arguments).
Extract this method to another class (perhaps using the method object pattern) that's easier to test on its own. This refactoring is called replace method with method object.
Usually, having to many parameters in constructors is a hint on bad conception. You'd better rethink you Objects and classes to reduce argument to give to the constructor.
If you don't want to, you can still use some kind of a "TestUtil" wich instantiate class for you.
Example :
public class MyTestUtils {
public createValidFirstClass() {
return new FirstClass(/* some arguments here */);
}
public createValidSecondClass() {
return new SecondClass(/* Some arguments here */);
}
public createValidThridClass() {
return new ThridClass(/* Some arguments here */);
}
public createValidExampleClass() {
return new ExampleClass(createValidFirstClass(), createValidSecondClass(), createValidThridClass());
}
}
This class MUST be in your test packages and not in your project, and should not be used outside of the tests, it would be a really bad practice here, use Factory or Builder for your real projects.
Anyway, i think that the best solution is to rethink you Classes.
Example :
public class People {
public People(String firstName, String lastName, Date birth, Date death) {
}
}
As you can see this is a pain in the ass to control that all given parameter was correctly formatted and not null.
This number of argument passed to a method can be reduced this way.
public class People {
public People(PeopleNames names, Period period) {
}
}
public class PeopleNames {
public People(String firstName, String lastName) {
}
}
public class PeopleNames {
public People(Date begin, Date end) {
}
}
Ok, it seems I found a way. Since the method is irrelevant to the state of the object, I could mock the object and order the MockRunner to use the real method when it is called. It is named partial mocking. The way of doing it is
ExampleClass = PowerMockito.mock(ExampleClass.class);
when(ExampleClass.methodToTest(foc)).thenCallRealMethod();
As far as I know, you cannot conduct a Test without initializing the class.
The three steps of Test are Arrange,Act and Assert. The class has to be initialized in the arrange part for fetching the required methods in the particular class you are testing.
I don't know what your method does but if it's possible for your application you could just make methodToTest static, which would allow you call it without an instance of the class.
Alternatively, you could avoid too much instantiation by creating one instance in a #BeforeClass method to be used for all tests, but again I don't know what you method does so that might not be desirable.
Use suppressions from PowerMockito.
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.api.support.membermodification.MemberMatcher;
suppress(MemberMatcher.constructor(ExampleClass.class))

Preventing a method being called before another one

This is question is a bit broad and conceptual.
I have a class with various methods. Let's call them A and B. How can I make sure that other developers working with this class in the future will not call method B before first calling method A at least once ?
I am doing this in C++ but in general what's the best way to enforce this ? I have naive some ideas such as using a boolean variable but I would like to hear some other thoughts as well.
One way to guarantee this? Make it the responsibility of method B to call method A once.
Anything else is a fragile API.
One way is to redesign your class a little differently. Consider a simple database class that needs to be initialized before being used. I'm a Java guy, so...
public class Database {
public void init(String username, String password) // must call this first!
public List<Object> runQuery(String sql) // ...
}
So I need to call init first. I can make a DatabaseFactory that does the initialization and returns the actual database object. We can hide the constructor so that only a DatabaseFactory can create a Database (in Java a nested class, in C++ a friend class maybe?).
public class DatabaseFactory {
public Database init(String username, String password) // ...
public class Database {
private Database() {}
public List<Object> runQuery(String sql) // ...
}
}
So now I must go through the Factory to get to the underlying object.
DatabaseFactory factory = new DatabaseFactory();
Database database = factory.init("username", "password"); // first init (call method A)
// now I can use database (or B in your case)
database.runQuery("select * from table");
Have a boolean variable that determines if A has been called. Then, when someone tries to invoke B without this boolean variable being set, throw an IllegalStateException.
Or you could have B simply call A since it seems that it cannot execute without A being called first anyways.
Otherwise, and since both methods are public, there's really no other way to enforce this.
Using a boolean is a good start, and throwing on access works OK.
However sometimes its nice to be able to enforce this at compile-time. In that case your only real option is to use some tricks.
Only expose A in your class, make it return a proxy containing B.
class MyClass {
public:
struct BProxy {
public:
MyClass * root;
void B() { root->B(); }
protected:
BProxy( MyClass * self ) : root(self) {}; // Disable construction
friend class MyClass; //So that MyClass can construct it
};
BProxy A() { ... return BProxy(this); }
friend class BProxy; // So that BProxy can call B()
protected
void B() { ... }
};
int main() {
MyClass m;
BProxy bp = m.A();
// m.B(); can't do this as it's private - will fail at compile time.
bp.B(); // Can do this as we've got the proxy from our previous call to A.
}
You can also achieve something similar using protected inheritance from a baseclass implementing (or providing a virtual) B().
One way to guarantee it is that A is done in the constructor of the class. If the constructor fails (throws) then the other developers do not have anything with what to do that erroneous B with. If the constructor succeeds then A is done at least once and so B is valid operation to do.
I would make method "A" the constructor to initialise the object. This has to called once to use the object, enforced by the compiler. Later you can call a method "B" in the knowledge that a constructor must have been called.

object reference passed through constructor

Im building a relatively large object-oriented program. I have a class called AerodynamicCalculator that performs numerous calculations and distributes the results around the system. My main concern is that my constructor signature is getting larger and larger as I add mor parameters to it.
As shown below I already have nine object references being passed into this constructor, but I need a further seven. Am I correctly creating this object? My understanding is that you pass the associated object references to the constructor and assign the class'es local variable to the object references. If this is the case the only way to get my class properly initialized with all the required objects is to pass them to the constructor, which is leading to a very long signature.
public AreodynamicCalculator(AircraftConfiguration config, AileronOne aOne,
AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r,
Rudder rr, RateGyros rG) {
// ...
}
Any advice on this approach would be very helpful, thanks in advance.
As mentioned - this may be a sign your class is doing too much, however, there is a commonly used 'solution' to this problem.
The builder pattern is often used in this situation, but it's also very useful when you have many constructors with different arguments, the builder is good because it makes the meaning of the arguments clearer, particularly when boolean literals are used.
Here is the builder pattern, the way this works is like this:
AreodynamicCalculator calc = AreodynamicCalculator.builder()
.config(theAircraftConfiguration)
.addAileron(aileronOne)
.addAileron(aileronTwo)
.addElevator(elevatorOne)
.addElevator(elevatorTwo)
.addRudder(rudderOne)
.addRudder(rudderTwo)
.build()
Internally, the builder will store all these fields, and when build() is called it will call a (now private) constructor that takes these fields:
class AreodynamicCalculator {
public static class Builder {
AircraftConfiguration config;
Aileron aileronOne;
Aileron aileronTwo;
Elevator elevatorOne;
Elevator elevatorTwo;
...
public Builder config(AircraftConfiguration config) {
this.config = config;
return this;
}
public Builder addAileron(Aileron aileron) {
if (this.aileronOne == null) {
this.aileronOne = aileron;
} else {
this.aileronTwo = aileron;
}
return this;
}
// adders / setters for other fields.
public AreodynamicCalculator build() {
return new AreodynamicCalculator(config, aileronOne, aileronTwo ... );
}
}
// this is the AircraftConfiguration constructor, it's now private because
// the way to create AircraftConfiguration objects is via the builder
//
private AircraftConfiguration config, AileronOne aOne, AileronTwo aTwo, ElevatorOne eOne, ElevatorTwo eTwo, Rudder r, Rudder rr, RateGyros rG) {
/// assign fields
}
}
Similarly to using the builder pattern, suggested in daveb's response, you can use a Dependency Injection framework like Spring.

Is it possible to do computation before super() in the constructor?

Given that I have a class Base that has a single argument constructor with a TextBox object as it's argument. If I have a class Simple of the following form:
public class Simple extends Base {
public Simple(){
TextBox t = new TextBox();
super(t);
//wouldn't it be nice if I could do things with t down here?
}
}
I will get a error telling me that the call to super must be the first call in a constructor. However, oddly enough, I can do this.
public class Simple extends Base {
public Simple(){
super(new TextBox());
}
}
Why is it that this is permited, but the first example is not? I can understand needing to setup the subclass first, and perhaps not allowing object variables to be instantiated before the super-constructor is called. But t is clearly a method (local) variable, so why not allow it?
Is there a way to get around this limitation? Is there a good and safe way to hold variables to things you might construct BEFORE calling super but AFTER you have entered the constructor? Or, more generically, allowing for computation to be done before super is actually called, but within the constructor?
Thank you.
Yes, there is a workaround for your simple case. You can create a private constructor that takes TextBox as an argument and call that from your public constructor.
public class Simple extends Base {
private Simple(TextBox t) {
super(t);
// continue doing stuff with t here
}
public Simple() {
this(new TextBox());
}
}
For more complicated stuff, you need to use a factory or a static factory method.
I had the same problem with computation before super call. Sometimes you want to check some conditions before calling super(). For example, you have a class that uses a lot of resources when created. the sub-class wants some extra data and might want to check them first, before calling the super-constructor. There is a simple way around this problem. might look a bit strange, but it works well:
Use a private static method inside your class that returns the argument of the super-constructor and make your checks inside:
public class Simple extends Base {
public Simple(){
super(createTextBox());
}
private static TextBox createTextBox() {
TextBox t = new TextBox();
t.doSomething();
// ... or more
return t;
}
}
It is required by the language in order to ensure that the superclass is reliably constructed first. In particular, "If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass."
In your example, the superclass may rely on the state of t at construction time. You can always ask for a copy later.
There's an extensive discussion here and here.
You can define a static supplier lambda which can contain more complicated logic.
public class MyClass {
private static Supplier<MyType> myTypeSupplier = () -> {
return new MyType();
};
public MyClass() {
super(clientConfig, myTypeSupplier.get());
}
}
The reason why the second example is allowed but not the first is most likely to keep the language tidy and not introduce strange rules.
Allowing any code to run before super has been called would be dangerous since you might mess with things that should have been initialized but still haven't been. Basically, I guess you can do quite a lot of things in the call to super itself (e.g. call a static method for calculating some stuff that needs to go to the constructor), but you'll never be able to use anything from the not-yet-completely-constructed object which is a good thing.
This is my solution that allows to create additional object, modify it without creating extra classes, fields, methods etc.
class TextBox {
}
class Base {
public Base(TextBox textBox) {
}
}
public class Simple extends Base {
public Simple() {
super(((Supplier<TextBox>) () -> {
var textBox = new TextBox();
//some logic with text box
return textBox;
}).get());
}
}
That's how Java works :-) There are technical reasons why it was chosen this way. It might indeed be odd that you can not do computations on locals before calling super, but in Java the object must first be allocated and thus it needs to go all the way up to Object so that all fields are correctly initialized before you can modify them.
In your case there is most of the time a getter that allows you to access the parameter you gave to super(). So you would use this:
super( new TextBox() );
final TextBox box = getWidget();
... do your thing...

Categories

Resources