Find out which method called me - java

I'm tring to find out a way to get the complete method signature that is calling me.
For example:
public class Called {
public void whoCallMe() {
System.out.println("Caller Method: " + new Throwable().getStackTrace()[1].getMethodName());
}
}
public class Caller {
public static void run(int i) {
new Called().whoCallMe();
}
public static void run(String str) {
new Called().whoCallMe();
}
public static void run(boolean b) {
new Called().whoCallMe();
}
/** MAIN **/
public static void main(String[] args) {
run("hi");
}
The way I've implemented whoCallMe() method I can see that run method called it, but since I 3 overloads I can't say which one was the caller cause whoCallme return only "run" as the method name.
Do you guys know other way where I could get the complete method signature like run(java.lang.String) ?

You can use AspectJ to create an aspect which will apply to every method invocation and add the details about the method being invoked to a per-thread stack, and then remove it after method completes. It's going to be insanely expensive, of course. Most likely you don't want to do that. Also you don't want to throw anything to find out who called you.
Basically the answer to your question is: do not do it.
Explain why you think you want to do it and somebody will give you a good alternative.
Also, come to think of it, you can argue that method overloading (not overriding!) is considered harmful. Do you really need multiple different methods with different arguments and the same name?

Related

Lambda body isn’t executed unless corresponding method is invoked

I am learning about Java Lambdas and I asked myself is it always required to call a abstract method of functional interface if I want to use the lambda here?
#FunctionalInterface
public interface A {
public void somefunction();
}
#FunctionalInterface
public interface B extends A {
}
public class testing {
public static void main(String[] args) {
B b = () -> System.out.println("MyText");
b.somefunction(); //Why do I need to call somefunction()
}
}
If I don't write b.somefunction(); I don't get any output even though the compiler does not give an error.
I don't pass any value to the method so why do I need to call the abstract method?
Is there anyway to skip the abstract method call? If my case was to add or perform some calculations, then I can understand that I need to pass some values in method, but in the above scenario I am just printing the value.
If you want the output to print when your program runs, write:
public class testing {
public static void main(String[] args) {
System.out.println("MyText");
}
}
If you want the output to print when some other function runs, then you might use a lambda:
class Testing {
public static void main(String[] args) {
runn(() -> System.out.println("MyText"), 10);
}
static runn(Runnable task, int times) {
for (int i = 0; i < times; ++i) {
task.run();
}
}
}
Lambdas exist to make it easy to specify a function whose execution you want to delegate to another entity. When the lambda is invoked, its arguments, and the treatment of its result are up to someone else.
A functional interface serves to provide a way
to define what is to be performed on a given call and
to define when it is to be called.
Normally, you'd define a "lambda object" as you did and then pass it to somewhere else to tell what to do under a certain circumstance. If you want to see it this way, it is a kind of callback.
The entity where you pass this object calls/uses it when it sees time to do so, or you do it yourself, as you do it in your example.

Check is instance method is called from a constructor

I would like to check, from an instance method of a non-final class, whether the constructors and initializers of that class and its chain of subclasses for the specific instance have already completed.
In the following example, I have a class Abstract, which can be used to implement an interface which allows listeners to be added (which, for simplicity, are just Runnable instances here) and which provides a method signalEvent() which calls all attached listeners.
abstract class Abstract {
protected final void signalEvent() {
// Check that constructs have run and call listeners.
}
public final void addListener(Runnable runnable) {
...
}
}
class Concrete extends Abstract {
Concrete() {
// Should not call signalEvent() here.
}
void somethingHappened() {
// May call signalEvent() here.
}
}
Now it is possible to call signalEvent() from within the subclass constructor, but there is no way that a listener has already been added by that time and the event would just be lost. In our code-base, once in a while, someone adds such a call and I would like to be able to catch such calls as early as possible (using an assert statement or similar).
Is it possible to check whether an instance method is being called, directly or indirectly, from the subclass constructor or initializer of the current instance or, alternatively, is it possible to check whether all constructors for an instance have been completed?
In short, there is no elegant Java mechanism that allows you to do that, but you may consider using a factory pattern. Instead of creating instances directly using new keyword, you could create a factory class, that takes care of creating the actual instance and invokes an additional "post-create" method, that lets the instance know it's been completely created.
If you're using some dependency injection like spring, you get that out of the box, but if not, a solution could look something like this:
interface PostConstruct { // the classes need to implement that
void postConstruct();
}
public class InstanceFactory {
public <T extends PostConstruct> T create(Class<T> clazz, Object... params) {
T instance = //create using reflection
instance.postConstruct();
return instance;
}
}
A solution to the problem to see if a method or code is being called from a constructor. The code below will print true and false respectivly but would be slow and not pretty at all.
I still believe it is not the right solution for the problem above. As Codbender said, better to check if a listener has been added or set a status variable which would be faster
Edit - fixed the issue that Codebender mentioned and also made sure to check back in the stack trace incase of being called a couple of methods deep
public class TestClass extends TestAbstract {
public TestClass() throws Exception {
submethod();
}
public void submethod() throws Exception {
System.out.println(isInConstructor());
}
public static void main(String[] args) throws Exception {
System.out.println(new TestClass().isInConstructor());
}
}
public class TestAbstract {
public boolean isInConstructor() throws Exception {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : elements) {
if (element.getMethodName().equals("<init>") &&
TestAbstract.class.isAssignableFrom(Class.forName(element.getClassName()))) {
return true;
}
}
return false;
}
}

Varargs and argument less method

I am just catching up with java 1.5, (yes i know its too early;) ) . while trying out few exercises on varargs , i just found something strange as below. the code compiles well and the varargs method is invoked only when i supply atleast one parameter. shouldn't this have been compiler error, a method and overloaded method with varargs. Or is there any specific usecase you may think, this scenario will
be useful
public class VarargsExample {
public static void main(String args[]) {
test1();
}
public static void test1(int... x) {
System.out.println("AssertionExample.test1(ARRAY METHOD)");
}
public static void test1() {
System.out.println("AssertionExample.test1(PARAM LESS)");
}
}
PS: tried to search this in SO, could not find similar one. pardon me if there is one already:)
Summary, thanks all for your quick responses. seems to be the normal methods are the one preferred. Same is the case when a single param method is present as below
public class VarargsExample{
public static void main( String args[] ){
test1();
test1(2);
}
public static void test1(int... x){
System.out.println("AssertionExample.test1(ARRAY METHOD)");
}
public static void test1(int x){
System.out.println("AssertionExample.test1(single param METHOD)");
}
public static void test1(){
System.out.println("AssertionExample.test1(PARAM LESS)");
}
}
First of call, the parameter-less overloading gets called because its signature is more specific than that of the overlauding with varargs. It is in general a very bad idea to have two overloaded methods which perform a completely different operation. So let's assume that the parameter-less method does the same thing as the varargs method when called without arguments, that is, the parameter-less method is a specialization of the varargs method.
Then a use-case is the following. Calling a varargs method always requires creating an array. Although, certainly at first, I wouldn't think about such minor optimizations too much, but it is an overhead which might, in some cases (for example in tight loop), be considerable enough. The parameter-less version of the method does not require creating an array, and additionally also may contain other optimizations for the specific case.
Sometimes, one sees more than one specializations, one with no arguments, one with one, one with two, and a general method. For example:
void doSomething() { ... }
void doSomething(String a1) { ... }
void doSomething(String a1, String a2) { ... }
void doSomething(String... as) { ... }
But I suggest to only do this in a late stage of development, if at all.

Verify that overriden superclass method is called when invoking this method on subclass

I'll show my problem using this example:
I have a class with a method foo. That class has a subclass which overrides this method.
Subclass' method calls superclass' method. Can I verify that?
I don't want to test what foo in superclass does. I just need to verify that it was called.
I know that refactoring could help (favour composition over inheritance, etc) but I am unable to do that.
Is there any way to achieve what I need?
Below is simple example of what I've tried
package tmp;
import org.junit.Test;
import org.mockito.Mockito;
import static org.mockito.Mockito.times;
public class Example {
#Test
public void test() {
// given
ChildClass childClass = new ChildClass();
ChildClass spyChildClass = Mockito.spy(childClass);
// when
spyChildClass.foo(100);
// then
Mockito.verify((BaseClass) spyChildClass, times(1)).foo(101);
}
}
abstract class BaseClass {
public void foo(int n) {
System.out.printf("BaseClass.foo(%d)%n", n);
}
}
class ChildClass extends BaseClass {
#Override
public void foo(int n) {
System.out.printf("ChildClass.foo(%d)%n", n);
super.foo(n + 1);
}
}
And this is the result:
ChildClass.foo(100)
BaseClass.foo(101)
Argument(s) are different! Wanted:
childClass.foo(101);
-> at tmp.Example.test(Example.java:19)
Actual invocation has different arguments:
childClass.foo(100);
-> at tmp.Example.test(Example.java:16)
Expected :childClass.foo(101);
Actual :childClass.foo(100);
<Click to see difference>
Obviously it's not what I wanted to see.
I can't modify BaseClass. I don't want to test BaseClass (I am not responsible for it). I don't even neet to know what exactly it does. I just need to verify that its method was called. Wnything else is not my problem. Its the problem of people who maintain BaseClass.
Test the behaviour of the class, not it's implementation.
Write the test such that the method is called and is expected to do something. Next check the object now represents what you now expect it to represent.
If BaseClass.foo is expected to increment some counter by 100, yet Subclass.foo increments some counter by 50 then calls the superclass, verify that the counter is now 150 and not just 50.
Don't peek the how - they may change over time. Do test the behaviour. The method foo may do other things besides increase counters - check the state of the object not what it did.
Possible solution: Make foo final, and decree that subclasses need to override some other method, the implementation of foo, instead of the actual foo.
abstract class BaseClass {
private boolean myFooCalled;
public final void foo(int n) {
myFooCalled = false;
fooImpl(int n);
if (!myFooCalled) { ... }
}
public void fooImpl(int n) {
myFooCalled = true;
System.out.printf("BaseClass.foo(%d)%n", n);
}
}
Notes: This is off the top of my head, so (1) I haven't tested it, (2) I'm not sure if this is what you really want, (3) I'm not sure whether your design ought to be improved. This is a general answer about "how you could make sure an overriding method calls the superclass method", not an answer tailored to your purposes.
I hesitate to give this answer because everyone here (including the OP) knows you can do this... but to answer the OP's question you can do this:
Instead of having
#Override
public void reset() throws IOException{
// ...
super.reset();
}
do this:
#Override
public void reset() throws IOException{
// ...
callSuperReset();
}
void callSuperReset() throws IOException {
super.reset();
}
... and verify that callSuperReset was indeed called...
I am a mocking newb (no doubt it shows), and I thought for a long time the command was simply "Thou shalt not create methods just to suit your tests".
But in a previous question of mine, davidxxx in his answer says
In fact I would say rather : "thou shalt not create methods to suit
your tests and that open the API of the application in an undesirable
way"
Given that this method callSuperReset is package-private, is there any problem in principle with it? (other than its total inelegance)
Yes, such a test can be written. And there is nothing wrong with wanting to do it, provided what you are testing is the contract of an API, not its implementation.
Here is a test for the contrived example in the question, using the JMockit mocking API:
#Test
public void subclassShouldObeyContractOfBaseClass(
#Mocked final BaseClass anyBaseInstance)
{
new ChildClass().foo(123);
new Verifications() {{ anyBaseInstance.foo(anyInt); }};
}
If necessary (as dictated by the contract of BaseClass#foo(int)), the test could also verify the argument value passed to the base method as being n + 1 (or whatever).

How to avoid code duplication in overloaded constructors?

Say that I have one constructor that takes an input and another that uses a default value. Both constructors then proceed to process this data in exactly the same way. (Example below.) What are my options to avoid code duplication in this case?
(I've read the post how to reduce the code of constructor overloading, where the top answer suggests using the keyword "this". In my case, I guess I would need to use "this" to call the first constructor from the second one after the input has been stored. This however results in a compilation error: "call to this must be first statement in constructor".)
Example code:
public class A {
public A(String a) {
//process a
}
public A() {
String a = "defaultString";
//process a
}
}
EDIT: I'm taking a lot of fire for using an input dialog call in a class constructor (which I'm aware isn't exactly good practice). So I've changed the code example to direct the discussion away from this :).
One way is to have an init method:
public class A {
public A(String a) {
init(a);
}
public A() {
String a = "defaultString";
init(a);
}
private void init(String a) {
//process a
}
}
Say that I have one constructor that takes an input and another that asks for it via an input dialog.
Don't do that. It will make for horribly entangled and hard to maintain code in the long run. At least try to seperate UI concerns (input dialogs etc) from your object model (which you can feed a string in the constructor).
In my honest opinion you really don't want an overloaded constructor here.
You may want to try chaining your constructors:
public class A {
public A(String a) {
//process a
}
public A() {
this("defaultString");
}
}
If you want to use a dialog to get the string, I recommend you present the dialog before calling this constructor.
I think this is the preferred method:
public class A {
public A(String a) {
//process a
}
public A() {
this(JOptionPane.showInputDialog("a"));
}
}
I'm not sure it is ever a good idea to call something like a JOptionPane from a constructor. This is just an idea but you really should take the buildA from a static method and perform it where you actually are intending on asking the user for input and then just call a single constructor.
public class A {
public A(String a) {
this.a = a;
}
public static A buildA(String input){
if(input == null){
input = JOptionPane.showInputDialog("a");
}
return new A(input);
}
}
Another option for reducing code duplication between constructors is to use an initialization block. Initialization block code will run before the constructor.
See
http://geekexplains.blogspot.com/2009/06/initializer-blocks-their-alternatives.html for an example, or
http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/ for discussion of both static initializer blocks and instance initializer blocks.
Using this method, you could put the common code into the initializer block, then leave the different logic in the specific constructor.
public class A {
{
//initializer block - common code here
}
public A(String a) {
//constructor - specific code here
}
public A() {
//constructor - specific code here
}
}
This may not be ideal in all situations, but it is another way to approach the problem that I didn't see mentioned yet.

Categories