Single method class - pass dependcies to constructor or method - java

I have a very simple class that has a single method.
The method needs two objects passed to it to prepare an output and return the output.
Should the class be instantiated with these two objects passed to the constructor, or should those be passed to method when being called?
Currently I can see that the method will always be called only once per request and always with the same objects passed to it.

There are a lot of factors involved, but in general, the constructor should take arguments for configuration (if any configuration is needed), and the actual input should be passed to a method. Methods should be the "verbs" or "actions" in an object-oriented design, while classes should be the "nouns" or "machines."
Simply buying or building a toaster doesn't result in toast. Someone creates the toaster (think of that as constructing an object), then they or someone else executes an operation with it to make toast (think of that as calling a method).
So, in the absence of more information, I would recommend passing the objects to the method, not the constructor. Even if it's the same objects being passed every time.

Related

Instance and Static Methods in Java

I have a Doubt and i can't find it on google or on Youtube, so I am Asking here.
As we know,
Instance methods can call other Instance Methods directly without objects in the same class. However we need objects to call Instance method in a Static method.
I want to ask why is it so? How does Instance method calls other instance method directly without object but need an object to get called inside a Static method?
Because instance methods already have the object. You can access it with the this keyword. When you call an instance method in an instance method, it calls it on this unless you specifically call it on another instance. In a static method you don't have an object, so there is no this object to call it on. So unless you specify an instance there's no default to call it on.
Why doesn't the language force you to call it on this rather than assume? Convenience, it allows you to type a bit less. Its a common feature in other object oriented languages as well. There are languages that won't do it and require you to specify the object at all times.

To get the hashCode() of the object that calls a specific method in Java

What I'm trying to is to get 'hashCode()' value of the object that calls a specific method in Java. For example,
public class Caller {
public void aMethod() {
Callee calleeObj = new Callee();
calleeObj.aSpecificMethod();
//do something
}
}
What I want to know is Caller's hashCode() value which calls calleeObj.aSpecificMethod() during the runtime. It is for drawing an Object diagram like below.
As a constraint, I only can modify '.class' files using bytecode instrumentation techniques.
To do that, I've tried Javassist library to instrument inside Callee.aSpecificMethod() but this way cannot get the caller's object. The reason seems obvious because instrumented code on 'Callee.aSpecificMethod()' only can access codes on Callee class, not Caller class.
Is there any way to capture the hashCode() value of caller's object using Javassist? I'm considering ASM 5.0 also, but using ASM 5.0 is the last option because I've built many code based on Javassist until now.
As said by others, there is no way of the invoked method getting hands on the caller object, but so far, nobody pointed you to the reason why this will never be possible:
The big misconception about your request is that you assume that there has to be a “caller object”. But there is no such thing. Your method might get invoked by static methods, e.g. right from the main method of an application, but also from class initializers or from constructors, even during the super constructor invocation, in other words, at places, where an object exists in the context of the invocation but hasn’t fully constructed yet, hence at a place where hashCode() can’t be invoked.
If you haven’t considered these gaps in your idea, you shouldn’t start using Instrumentation to alter the caller’s byte codes. It’s very unlikely that you will produce correct code. Even at places where an instance exist at the call cites, that instance doesn’t need to be available, nor does hash code calculation. What if you method get invoked from another object’s hashCode method?
Besides practical obstacles, the big question is, why do you think you need the “callers” hash code? What ever you intend to do with it, it can’t be right. Think of the following code:
public class Caller {
public void aMethod() {
Callee calleeObj = new Callee();
new Thread(calleeObj::aSpecificMethod).start();
}
}
Whose hash code are you interested in? Of the instance of the anonymous class generated at runtime? Of the Thread instance invoking the run method of that anonymous class? Or of the Caller instance which won’t be on the call stack at all, when your method get invoked?
You have to pass either the calling object or its hash code as a parameter to the method.

Get parameter values of the calling method [duplicate]

This question already has answers here:
How to get arguments passed to method that called this method?
(6 answers)
Closed 3 years ago.
How to get parameter values of the calling method?
I have scenario where there are two classes viz., Class A and Class B containing two methods mthA(in Class A) and mthB(in Class B). mthA calls mthB. now I want to know in mthB that what all parameters have been passed to mthA. This is basically for logging and handling exceptions. I am able to get the class name of the calling class i.e Class A and the method name which is calling mthB i.e mthA. but I am stuck at getting the parameters of mthA.
Thread.currentThread().getStackTrace()[1].getClassName()
this gives me the class name of the calling method i.e Class A.
Thread.currentThread().getStackTrace()[2].getMethodName()
This gives me the method name of the calling method i.e mthA.
If somehow I can get the whole method itself then I can get the method parameters passed to this method by using getParameters().
There's no easy way to get calling method's arguments values, (if you can not change the parameters of called method to include and pass calling parameters values).
Using some APIs like what Thread provides, we can get the static info like class/method name, but not runtime info like arguments values. One way could be to store and manage that kind of info somewhere and show when required in case of logging/exception. I dont think there's an API for that in java.
There is simplest way or is it necessary to use Reflection..?
If you want to know what parameter is passed for mthA then pass same parameter to mthB also Ex:
mthA(1stParam, 2ndParam, ...){
mthB(1stParam, 2ndParam, ..., OtherParamertsForMthB);
...
}
If it is just for logging purpose only, then you should log in mthA itself all the arguments passed into the method.
Why should mthB know about mthA's argument values to handle exceptions? If you are doing that, then you should consider refactoring the code and handle exceptions at the appropriate levels. If values passed to mthA is leading to an exception, then it should be handled there itself before calling mthB.
Reflection only helps in getting static information of the class and methods and does not provide runtime values of the arguments passed into a method.
Why don't you use some AOP tool like AspectJ to capture these values and log? You can use execution() point cut along with after() advice. For non production deployment you can log all the method calls along with passed values and returned value. This will be too much overhead for production env. For that you can just store the passed values (Object args[] as you get in AspectJ advice) in local variable and only log it in case of exception. But even in that case there will be some performance penalty as primitive values will be boxed to be passed as Object[] to your advice.

Can we stop the run of a constructor?

I need to create an object of some type.
The class of the object has just one constructor (one that I've written).
My program receive requests to create instances of an objects with a parameter ID.
I want to stop the constructor if the ID parameter contains a char that is not a digit.
I cannot check the parameter before, since I'm not the one who calls the constructor.
Make the constructor private and expose a static factory method, that will validate and return a new instance of the object if the parameter is valid.
The only way to "stop" a constructor is to throw an exception. Bearing in mind of course that the caller is supposed to "know" about this exception and be able to handle the case where the constructor fails.
Throwing an exception from the constructor doesn't stop the object being created though, It just makes the assignment of its reference to a variable fail and the reference unavaliable (and therefore eligible for garbage collection) unless you make the mistake of passing this to an external method from the constructor itself. (Which you shouldn't do anyway.)
How to solve this depends on what you want to happen when an illegal character is given, which in turn depends on what object we're talking about, and how the consuming library is using it.
The most reasonable thing to do would be to throw an IllegalArgumentException, and this is what I'd suggest you do.
However, it might make sense to just return null, too, even though I'd strongly recommend against it (you can't do this directly in the constructor, but you can create a factory method that does this).

Instance Method call in Java

In Java, for each object, a new copy of instance variables is created which can be accessed using the object reference.
But in case of an instance method, only one copy of it(instance method) exists.
How is this method accessed by various object references?
The byte code (or native code if it's JIT'd) for the method is stored in one location. When the method is called, a pointer (under the hood, aka reference at a higher level) to the instance object is passed as the first argument so the method code can operate on that specific instance - have access to its fields, etc. In order to save space without additional performance cost, the calling mechanism in Java is quite a bit more complicated than C++, especially for interface methods.
Methods and fields are completely different. Methods apply to all instances of the object, but fields are per instance.
One way to think of it:
pretend the method is "global" to all instances, but it is "passed" an instance of the object via the "this" reference.
Methods can change the state of a particular instance, but they themselves are stateless.
Behind the scenes a reference to the object is passed to the method as part of the call. It may be useful to look at Java's reflection classes, Method.invoke() in particular.
From a previous answer of mine:
I'm sure the actual implementation is quite different, but let me explain my notion of method dispatch, which models observed behavior accurately.
Pretend that each class has a hash table that maps method signatures (name and parameter types) to an actual chunk of code to implement the method. When the virtual machine attempts to invoke a method on an instance, it gets the object's class, and looks up the requested signature in the class's table. If a method body is found, it is invoked, providing the original object as a reference called this.
Otherwise, the parent class of the class is obtained, and the lookup is repeated there. This proceeds until the method is found, or there are no more parent classes—which results in a NoSuchMethodError.
If a super class and a sub class both have an entry in their tables for the same method signature, the sub class's version is encountered first, and the super class's version is never used—this is an "override".
the implied reference "this" is passed in to each method, which of course you can reference explicitly
I'm assuming you're meaning on a simplistic level, as in how you actually do the call.
I'm also assuming you're refering to a method that has the static modifier in its signature, ie:
public static int getNum()
{
// code in here
return num;
}
If this is what you mean, and this was part of a class called 'SomeClass', then it would be accessed via the method call SomeClass.getNum(). ie, you put the actual class name before the method.
If this is not what you mean, ignore my answer :)

Categories

Resources