Invoking the caller of a method in Java [duplicate] - java

This question already has answers here:
How do I find the caller of a method using stacktrace or reflection?
(13 answers)
Closed 9 years ago.
Just wondering, how do you find out the name of the method that invokes another method? I want to use the Method class.

You can make use of StackTraceElement :
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
Order of elements in StackTraceElement array: The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.
Once you have the desired method name then you can call it using reflection :
Method lastMethod = YourClass.class.getMethod("yourMethodName");
lastMethod.invoke();
Note: The code should be changed as per your class and method.

Getting the name is tricky enough, getting the method is very hard because you don't know the argument list but you do know the class and you can use the line number when reading the byte code to find which method which contains that line. If the method is static (and I suspect its not) you are ok. If you need an instance, finding that is next to impossible in any portable way.
The sort of thing you are trying to do is the Java equivalent of saying; how do I learn to flight in a couple of easy steps.
What ever your problem is this is highly unlikely to be a good solution. If you need to call back to the object which called you, you should pass that object as an argument, ideally via an interface.
When ever you find the code running back on itself, this is sure to end in a mess of some kind, You want to simplify your dependencies.
What you should do is something like this.
interface Callback<T> {
onResult(T t);
}
class A implements Callback<MyResult> {
B b = new B();
public void method() {
b.doSomething(this);
}
public void onResult(MyResult mr) {
// do something with mr
}
}
class B {
public void doSomething(Callback<MyResult> cb) {
// do something
cb.onResult(new MyResult(something));
// do something else
}
}
Of course this would be all much simpler if instead of call back on the first method, you just returned a result and half this code wouldn't be needed. This is why normally when you want to pass something back to the caller, you use a return value instead of recursion.

Related

Lambda Expressions and Non-Class Java Methods [duplicate]

This question already has answers here:
Non-class functions in Java
(4 answers)
Closed 2 years ago.
When declaring methods in Java, do they need to be a part of a class? I am familiar with the idea of a Utility Class:
"Utility Class, also known as Helper class, is a class, which contains just static methods, it is stateless and cannot be instantiated. It contains a bunch of related methods, so they can be reused across the application."
However, can one just create a method separate from any class altogether? (I'd assume scope becomes public by default and declaring anything else for scope might result in an error).
If this is not possible, perhaps that would explain the need for Utility Classes, but I wasn't sure as I hadn't thought about this before - I assumed naturally you could make functions separate from any specific class, but I had been looking through various code samples and couldn't find a specific example where this was occurring.
Part of the reason I am asking this is I was reviewing this article (and mentioned in point 2):
https://www.geeksforgeeks.org/lambda-expressions-java-8/
In it, it states: Lambda expressions are added in Java 8 and provide below functionalities.
1) Enable to treat functionality as a method argument, or code as data.
2) A function that can be created without belonging to any class.
3) A lambda expression can be passed around as if it was an object and executed on demand.
Java is a sort of purely class-based programming language. So, Yes, it and everything needs to be a part of a class.
You are right, you can make a Utility class making methods public static in this way methods can be called without instantiating the class.
Answer to question in the comment:
Why would someone write Object.method() instead of just method()?
Object class is a standard class in java.lang package. You should not create your class named Object otherwise you will need to specify java.lang.Object everywhere you use java.lang.Object.
Now you probably meant
Why would someone write MyUtilClass.method() instead of just method()?
Suppose you have a class MyUtilClass as follows
public class MyUtilClass {
public static int utilMethodA() {
return 1;
}
public static boolean utilMethodB() {
int value = utilMethodA();
if(value == 1)
return true;
else
return false;
}
}
And suppose you have another class MyClass as
public class MyClass {
public void classMethod() {
int value = MyUtilClass.utilMethodA();
}
}
Here if you see in MyUtilClass, utilMethodB() uses utilMethodA() without writing MyUtilClass.utilMethodA() (however, we could write it that way also). Here we did not need to write it as MyUtilClass.utilMethodA() because compiler can find the utilMethodA() without fully specifying it's class because it is present inside it's own class.
Now, In Myclass's myMethod(), we must specify MyUtilClass.utilMethodA() (without it, it won't work), because the compiler has no way of figuring out that you meant to call utilMethodA() of MyUtilClass. There could be hundreds of classes with a method named utilMethodA(), the compiler has no way of finding out which one of the hundred methods you want to call.
Note:-
Also, you can do static import of MyUtilClass.myMethod() like
import static my.package.name.MyUtilClass.myMethodA()
and then use utilMethodA() inside MyClass without prefixing MyUtilClass (but you already informed compile by static import that you will be using utilMethodA() of MyUtilClass right?)
Looks cool to you? No!
This is rather a bad way because
It makes code looks unobvious. In a large class, it may seem that
method utilMethodA() is a local method defined somewhere in
MyClass.
Also, it can generate ambiguity to the compiler if more than one static import of utilMethodA() is done. As compiler has no way of figuring out which of the two you intend to use.
(Edit) Regarding Lambda Expression
Lambda expression is pretty cool stuff added in Java 8. They are basically a kind of function. They provide you the power to define a function right where they need to be used. For example in this link that you provided, see the example shown below syntax of lambda, there the statement
ArrayList<Integer> arrL = new ArrayList<Integer>();
arrL.add(1);
arrL.add(2);
arrL.add(3);
arrL.add(4);
arrL.forEach(n -> { if (n%2 == 0) System.out.println(n); });
Basically, what we are doing here is, we are defining a function, if n is multiple of 2, we print n. We are doing it forEach element of arrL. Did you see, we defined the function to be executed on each element right inside a function call forEach(). That's the beauty of lambda expression.
Now, coming to your question,
So the primary benefit of lambda (besides syntax) is to make it easier to implement functional interfaces (compared to what alternative)?
Yes, sort of. Easy in terms of not creating a separate class implementing the interface and then implementing the abstract method and then calling that implemented method.
This becomes lots of work, especially if you need to call that method only once for example,
Consider the Functional Interface FuncInterface defined as in the link in your question:
interface FuncInterface {
// An abstract function
void abstractFun(int x);
// A non-abstract (or default) function
default void normalFun() {
System.out.println("Hello");
}
}
Now, you want two kind of implementation to your functional interface:
One that provides twice of the passed int x.
Another one that provides square of passed int x.
So, you make two implementations of it:
First FuncInterfaceTwiceImpl
public class FuncInferFaceTwiceImpl implements FuncInterface {
#Override
public void abstractFun(int x) {
System.out.println(2 * x);
}
}
Second, FuncInterfaceSquareImpl as
public class FuncInterfaceSquareImpl implements FuncInterface {
#Override
public void abstractFun(int x) {
System.out.println(x * x);
}
}
Now, you call them as
public class MyClass {
public static void main(String[] args) {
FuncInterface interfaceTwiceObject = new FuncInferFaceTwiceImpl();
interfaceTwiceObject.abstractFun(5);
FuncInterface interfaceSquareObject = new FuncInterfaceSquareImpl();
interfaceSquareObject.abstractFun(5);
}
}
It prints
10
25
Now, what you had to do?
You had to create two separate Classes (in separate new files or
could have made private classes in the same file that of MyClass),
each implementing the abstract method.
Then you instantiated objects of each class and called them
respectively in the main function.
What if this is the only place where you had to call this twice and square thing? You had to make two classes just to use them only once. This effort is too much!!
What if you want to call it without creating new classes and implementing methods in a class?
What if I tell you only provide me the method body, I will do the work for you without you to bother about implementing interface and overriding methods?
Here comes the Lambda magic. Instead of making any impl classes just
head straight towards the main method
Instantiate two objects of FuncInterface providing only method body in Lambda expression.
Call abstract method from objects just like below
public class MyClass {
public static void main(String[] args) {
FuncInterface interfaceTwiceObject = (n) -> System.out.println(2*n);
interfaceTwiceObject.abstractFun(5);
FuncInterface interfaceSquareObject = (n) -> System.out.println(n*n);
interfaceSquareObject.abstractFun(5);
}
}
And boom, the output is
10
25
Just one more time where Lambda saved your day!!
Yes all methods in Java have to be part of a class. You cannot create a method (static or otherwise) which is not associated with a class.
EDIT
Before I answer your question, I will point out that lambda expressions were introduced in Java 8 through the concept of SAM types. In addition, a bit of syntactic sugar was also introduced to facilitate the creation of these types.
When you hear the term "Lambda expression" in Java, you should always remember that they are expressions. Your confusion stems from thinking that lambda expressions evaluate to a pure function not associated with a class or object; well this is simply not the case in Java and I will show you why.
Lambda expressions are not functions
I can now see where your confusion comes from because that article you are reading made a false claim when they say that lambda expression is:
A function that can be created without belonging to any class.
This is simply not true. A lambda expression in Java is not a function. Take the example they give for instance.
interface FuncInterface
{
// An abstract function
void abstractFun(int x);
// A non-abstract (or default) function
default void normalFun()
{
System.out.println("Hello");
}
}
class Test
{
public static void main(String args[])
{
// lambda expression to implement above
// functional interface. This interface
// by default implements abstractFun()
FuncInterface fobj = (int x)->System.out.println(2*x);
// This calls above lambda expression and prints 10.
fobj.abstractFun(5);
}
}
Proof
Now take the comment they have in the main method:
lambda expression to implement above functional interface
From the start they admit that the next line of code implements a functional interface. However functions in Java do not implement interfaces, only classes or other interfaces can do that!
Now, they even go ahead and "call" this function:
This calls above lambda expression and prints 10.
except instead of directly invoking the function (as anyone would if this was really a function), they use the property accessor notation (.) to access the actual method they wanted to call, which means what we have here is not a function, but actually an instance of an anonymous class.
Furthermore, since this object actually contains another method (normalFun), one might ask the question, which one do I use when I want to pass this "function" to another method? This is not a question that is commonly (if ever) asked in the context of lambda functions because there is only one thing to do with a lambda function and that is to call it.
In closing
Java has lambda expressions, not lambda functions.
What makes it a lambda expression is simply the syntactic sugar introduced in Java 8 that uses the () -> { } notation. Unfortunately, many fans of functional programming began associating the term "Lambda function" with objects created using this syntax, and this has led to the confusion you have expressed in your question.
To rehash what I answered previously, all functions in Java are part of a class, and you cannot have a function which is not associated with an object, nor can you create a function outside a class.
HTH

Is it possible to reference different methods with one method call in a for loop?

I have a plan to make a GUI as minimal as it gets. I have hit a brick wall where I cant find an answer or maybe some kind of workaround due to me being inexperienced in java.
I have searched quite a bit and only found ways to replace the last letter or number in a string but not in a method call
public static int question;
public static void main(String[] args) {
int questionNumber = Integer.parseInt(JOptionPane.showInputDialog("Enter project no."));
if (questionNumber>=7){
questionNumber=6;
}
else if(questionNumber<=3){
questionNumber=4;
}
question = questionNumber;
System.out.println(question);
System.out.println(questionNumber);
for(int i=4; i<=6;i++)
if(question==i){
Question4(); // want the number 4 to be the question variable
}
}
What I would expect is
for(int i=4; i<=6;i++)
if(question==i){
Question *the variable "question" here* ();
}
and have no idea if that is possible or how to get there.
Is it possible to reference different methods with one method call in
a for loop?
Yes. It depends upon what exactly you mean by different methods. Here are three general ways in which this can be achieved:
The Java enum facility allows developers to define constant-specific methods, which are different method bodies defined in each separate enum constant declaration. The actual method body that is invoked depends upon the actual enum constant upon which the method call is made (this is actually a specialization of the next bullet item).
Interfaces enable different method bodies to be defined in each separate implementation. In this way, the actual method body that is invoked depends on the instance of the actual implementation upon which the method call is made.
Another way to invoke different method bodies with "the same method call" is to perform method invocations using Java's Reflection Facility. Since Java is an Object-oriented development environment, a decision to use reflection should be made carefully. Reflection is (often much) slower, less readable, and clumsier than solutions that don't use it. Reflection also makes many errors which could be detected at compile-time detectable at run-time only.
In Java, the principle mechanisms of abstraction are classes and interfaces and, so, when thinking about a problem domain and resolving that into an object domain you should be thinking about how to design interfaces and classes that provide the most natural description possible.
You want to be able to invoke a method that corresponds to a particular question. A better way to approach this is not to abstract over it with the method call to a question, but to abstract over the questions themselves. Your project has questions, so this is a good clue that you should have a Question class.
Here is a skeletal solution to the problem that makes use of the Java enum facility (enums are a special kind of class). This solution is similar to the one suggested by Matthieu but it does not need reflection at all; instead it uses the first bullet item above and defines constant-specific methods (which is, itself, a specialization of the second bullet item above):
public enum Question {
QUESTION_1 {
#Override public String getText() {
return "This is the text for Question #1.";
}
},
QUESTION_2 {
#Override public String getText() {
return "This is the text for Question #2.";
}
},
:
:
QUESTION_N {
#Override public String getText() {
return "This is the text for the final question in the series.";
}
};
public abstract String getText();
}
This enum class defines one constant for each question in the series of questions (each of these constant declarations becomes an instance of the enum class Question at run-time). Each declaration defines a different method body for the method getText() which is overridden inside each enum constant.
The declaration public abstract... at the end of the enum informs the compiler that every enum constant must provide an implementation for the getText() method. If a developer adds a new question to the series but forgets to add a getText() method in it, the compiler will complain (this is a type of error that can be caught at compile-time with an object-based solution that could only be caught at run-time if reflection were used).
Here is a simple program to exercise your Question enum class. It simply prints out the name of each question constant followed by its question text:
public static void main(String[] args) {
for (Question question : Question.values()) { // here is the "one for loop"
String text = question.getText(); // here is the "one method call"
println(question.toString());
println(text);
}
}
No reflection is used. Instead, natural abstraction mechanisms of Java's type system are able to achieve the desired goal of invoking a separate method body for each question.
Using map in this situation is most easiest solution. You should learn how to use them and how they works but, this is more about design now. If you want pass some parameters into your method take a look on Consumer, BiConsumer or even Function class provided by java. Check this example how it could implementation looks with Runnable that takes no parameters.
Map<Integer, Runnable> map = new HashMap<>(); // creating Map variable
// registering questions
map.put(1, () -> {
System.out.println("Question #1");
});
int questionNumber = 0;// get option id
if (map.containsKey(questionNumber)) { // first check if question is registered
map.get(questionNumber).run(); // get runnable that is registered with exact questionNumber and run it
} else {
// print invalid question number
}
You can use reflection:
try {
Method m = MyClass.class.getDeclaredMethod("Question"+questionNum);
m.invoke(this);
} catch (NoSuchMethodException e) {
// Handle
}
But you should handle the exception properly, because it will most probably fail one day or another.
You can also use an enum to define each behavior and call the appropriate:
private static enum EnQuestion {
Question1 {
public void run(MyClass instance) {
// ...
}
},
Question2 {
...
},
...
QuestionN {
...
};
public void run(MyClass instance);
}
The enum has to be static so you can't access MyClass protected/private fields and methods.
Then call it:
EnQuestion.values()[numQuestion].run(this);

JAVA: Getting a count, how many times a class is being called in other classes [duplicate]

This question already has answers here:
How to Count Number of Instances of a Class
(9 answers)
Closed 4 years ago.
Suppose I have a demo.java class and have other classes like A.java , B. Java and so on.
I want to write some code in Demo.java to get the count , that will tell in how many classes Demo.java is getting called.
Any suggestions would help. Thanks in advance!
Create a static variable in class.
public static int callerCounter=0;.
And then increment it in every constructor. E.g:-
Demo()
{
callerCounter++; // Add this line in every Constructor
}
And Print callerCounter where you want to get counter value.
I do not think it is doable in general case by just analyzing the code. If the interface is in use, may not be trivial to know which class will be instantiated behind the interface. This may depend on decision within some factory and may influenced by the input that is only available at runtime, well, even by SecureRandom theoretically.
You can always put either counters or just logging statements (processing the log output separately) to collect this kind of statistics at runtime. Tools like JProfiler may work as programming-free alternative.
Create a static Set callerClasses to hold the name of each class that called your Demo class.
Then, at each call to your Demo class, add the caller name to the set.
At any point in time you can check how many different classes called your Demo class by inspecting the Set size.
EDIT NOTE #1:
The question was made clear after I posted my answer that the intention is not count for calls on methods but count instances created.
I will keep it anyway because this may be the case for someone else.
EDIT NOTE #2:
Added code sample for completeness.
public class Demo {
// ConcurrentSkipListSet for thread safety
private static Set<String> callerCount = new ConcurrentSkipListSet<>();
public void methodA() {
String className = new Exception().getStackTrace()[1].getClassName();
recordCaller(className);
}
public long getNumberOfCallers() {
return callerCount.size();
}
private void recordCaller(final String className) {
callerCount.add(className);
}
}

how can i find all the methods that are called by reflection

For example:
public class Demo{
public String getReflectString() {
return "string from reflect";
}
public String reflectMethod() throws Exception {
Method method = ReflectCase.class.getMethod("getReflectString");
return (String) method.invoke(this);
}
}
Method Demo#getReflectString called by reflection,and I wanna find a way to get all the methods in the program that are called this way.
I came up with a solution that has not yet been implemented.
Read the contents of the class file, start from the instruction, find the Method#invoke
instruction, and then look back to find the instance that calls the method, and then get the instance corresponding Class and MethodName.
However, this method has a problem, if Class or MethodName or even Method are passed as a parameter, it is difficult to find the corresponding content.
On this basis, think of ways to improve, traverse all the methods, check the instructions of the method. If got Method#invoke instruction in method A(), and Class and MethodName are passed in as parameters, record method A() and the order of parameters. In the following check, if there is a method call A(), you can get the value passed to method A() Parameters, to obtain the required value.
However, this solution requires traversing the entire program's instructions, which can be very time-consuming when the program is very large. If method call too many levels, the implementation of the algorithm can be quite complicated. So would like to ask, the feasibility of this idea, or is there any better way to solve the problem.
Thanks in advance.

What is the purpose of using the "this" keyword in this code snippet? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 5 years ago.
public class Leaf {
int i=0;
Leaf increment() {
i++;
return this;
}
void print() {
System.out.println("i= "+ i);
}
public static void main(String[] args) {
Leaf x =new Leaf();
x.increment().increment().increment().print();
}
}
Output:
i=3
Till now I know that the this keyword is used to produce the reference to the object that the method has been called for. So in this code, the object x is calling the method increment and the this keyword gives a reference to x. But then, how does that help one in performing multiple increments as in the following line?
x.increment().increment().increment().print();
You have posted an example of method chaining; the linked Wikipedia entry says (in part)
Method chaining, also known as named parameter idiom, is a common syntax for invoking multiple method calls in object-oriented programming languages. Each method returns an object, allowing the calls to be chained together in a single statement without requiring variables to store the intermediate results.
In x.increment().increment().increment().print(); each increment() is chained to the next call. And, increment begins with i++ so each call increases i by 1. It is functionally equivalent to
x.increment();
x.increment();
x.increment();
x.print();
See also, the StringBuilder.append() methods; they also return this to allow method chaining like
System.out.println(new StringBuilder("Hello ").append("World"));
Nothing fancy or vague is going on here, the question is
how does that help one in performing multiple increments as in the following line?
You are calling the the increment() method thrice, as simple as that, the increment method id returning an object that class only so the increment method can be called again. So if x is an object of type Leaf, x.increment is also an object of type Leaf(return type of increment is Leaf), so increment method can be called again. Every time the increment method is being called we are incrementing the i by 1.
Pleae let me know if its still not clear.

Categories