Call a method when another method is called? - java

Now I am very aware that you can simply do the following:
public static void methodA() {
doSomeOtherStuffHere();
methodB();
}
public static void methodB() {
doStuffHere();
}
But in my scenario, I cannot change the code of method A ( I cannot add the methodB(); ). So is there any way I can detect when method A is called (and then execute method B when it is)?

You can use Aspect Oriented Programming (https://www.baeldung.com/aspectj) to create aspect which will be executed before YourClass.methodB()

In plain Java, you can do this by creating a subclass of the Class (Which owns methodA) and override the method methodA. Write your own Implementation and use the subclass method where ever you need.

in you code you have "doSomeOtherStuff()" method. You could place methodB within it. Here is an example:
public class App{
public static boolean isCalled = true;
public static void main( String[] args ){
starterMethod();
}
public static void methodB() {
System.out.println("Method B started");
}
public static void starterMethod() {
methodB();
}
}
In you example you can call "doOtherStuffHere". You could call methodB within doOtherStuffHere and that method could contain a call to methodB.

Related

In java constructor and main which one will execute first?

Basically which one will execute first the main method or the constructor?
public class ConstructorExp {
public ConstructorExp() {
System.out.println("Ctt");
}
public static void main(String[] args) {
System.out.println("Inside Main Methos");
System.out.println("Main");
}
}
The main method will always be excecuted first, because it is a special static method that will be called from Java itself to start an application.
For more about the main method please read Java main() Method Explained for example.
Constructors will be created on object creation - in your case no object creation happens - so the constructor will never be executed.
You could modify your example to also execute the constructor:
public class ConstructorExp {
public ConstructorExp() {
System.out.println("Ctt");
}
public static void main(String[] args) {
System.out.println("Inside Main Methos");
ConstructorExp example = new ConstructorExp();
System.out.println("Main");
}
}
Be carefully, because the example object is never used the constructor call might be eliminated by some kind of optimization depending on the compiler you are using.

ambiguity in invoking a method inherited from another class

I have two java class files
Hi.java which belongs to second package
package second;
public class Hi {
protected int v=20;
protected void m(){
System.out.println("i am protectTED");
}
}
S.java which belong to first package
package first;
import second.Hi;
interface i1
{
void m();
int a=200;
}
interface i2{
void m1();
int b=100;
}
class S extends Hi implements i1,i2
{
int a=50;
public void m()
{
System.out.println("hi");
}
public void m1()
{
System.out.println("hello");
}
public static void main(String[] args) {
S s=new S();
/*need correction here (i don't know the exact syntax to mention to get
the desired output)
s.m(); //should invoke method m() from class Hi only.
s.m(); //Should invoke method m() from class S only.
*/
//the following statements prints the desired values
s.m1();
System.out.println(s.v);
System.out.println(i1.a);
System.out.println(s.a);
System.out.println(b);
}
}
when i run the S.java class file method m() in class Hi should be invoked.("my intention") instead method m() of the same class i.e., class S is being invoked.
How to differentiate the 2 methods for invoking. Is it even possible?
when i run the S.java class file method m() in class Hi should be invoked.("my intention") instead method m() of the same class i.e., class S is being invoked.
Correct, because you've overridden it with m in S. Overriding methods is fundamentally different from overriding fields. (And in general, it's best to avoid overriding any fields that are visible to your subclass, as you're doing with a.)
In instance code in S, you can run the inherited m via super: super.m(). But you cannot do that from static code, not even static code in S. You could give yourself a private callSuperM in S:
private void callSuperM() {
super.m();
}
...and then use that in main:
s.callSuperM(); // "i am protectTED"
s.m(); // "hi"

Java execution flow?

what will be the flow of execution in case of override? What i believe is , when we call a constructor/object of any class, during execution first it call parent constructor and than child. but what will happen in case of over ridding?
lets suppose:
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
Out put of this code is:
In Class b
In Class b
what i don't understand is, why it's printing "In Class be" only, it should be "In class A and, In Class b",
when i remove override method from class b. it give me desired output.
All java methods are virtual. It means the method is called with using actual type of this. So inside of constructor A() {} this is the instance of B, so that is why you've got its method call.
Calling like this printStatus() will call the method from the same class. If you call with super.printStatus() it will envoke method from the super class (class which you have extended).
When you over-ride a method you over-ride it completely. The existence of the original implementation is completely invisible to other classes (except via reflection but that's a big topic of its own and not really relevant). Only your own class can access the original method and that is by calling super.methodName().
Note that your class can call super.methodName() anywhere, not just in the overriding function, although the most usual use for it is in the overriding function if you want the super implementation to run as well as your own.
Constructors are a slightly special case as there are rules about how and why constructors are called in order to make sure that your super-class is fully initialized when you try and use it in the inheriting class.
super is always called whether you write super(); or not.
In the example printStatus() method of Class A will never be called. Since you are creating an instance of class B and there will be method overriding. You can use the following to call the Class A printStatus() method.
public B()
{
super.printStatus();
}
When you override a method, it will override the one that you expect from class A.
Should use super keyword for calling super class method.
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
Constructor public B(){ super.printStatus(); } calls Class A print method and constructor public A(){ printStatus(); } calls Class B print method since you've overridden.
But its wrong with overridable method calls in constructors.
Try with like this :
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
For better understanding the concepts of Overloading and Overriding just go through this links:
http://en.wikibooks.org/wiki/Java_Programming/Overloading_Methods_and_Constructors

Equivalent to late static binding(PHP) in other popular languages

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); // Outputs "B"
?>
I want to get an equivalent in Java...so something like
class A {
public static void who(){
System.out.println("A");
};
public static void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
public static void who(){
System.out.println("B");
};
public static void main(String[] args){
B.test(); // Outputs "A" but I want "B"
}
}
I want the who() call inside A::test to resolve as in PHP 5.3 by calling B::who.
EDIT: I know there is no "standard way" of doing this in most popular languages. I'm looking for hacks and such. Also, is this possible in C/C++, or any other popular OOP language?
This is not for any real design on anything. I'm just being curious.
Not possible in Java. (At least not without ugly reflection hacks.)
I encourage you to rethink your design and rely on proper objects.
Related question:
Can I override and overload static methods in Java?
Edit: B.test() will (or can at least according to spec) be compiled into a call to A.test(), so there's no way to discover how the call was made from within A.test(). In other words, there's no way to let the behaviour of A.test depend on if it was called through A.test() or B.test().
Since you're asking out of curiosity, here's AFAIK the closest "solution".
Overload test with a test(Class<?> c) which takes as argument the class which defines the intended who method.
Hide (note that you can't override) test() in class B.
And change the implementation of A.test slightly.
In code:
class A {
public static void who() {
System.out.println("A");
}
public static void test() {
test(A.class);
}
public static void test(Class<?> c) {
//who(); //<<< How to implement a static:: thing here???
try {
c.getMethod("who").invoke(null); // Call static who on given class.
} catch (Exception e) {
}
}
}
public class B extends A {
public static void who(){
System.out.println("B");
}
public static void test() {
test(B.class);
}
public static void main(String[] args){
A.test(); // Outputs "A"
B.test(); // Outputs "B"
}
}
It seems that the compiler generates a call to B.test in the bytecode even though B doesn't declare a method named test.
Bytecode of main method:
invokestatic #5 = Method B.test(()V)
return
Given the names of a class and method ("B" and "who") you can easily use reflection to call the method. So the question becomes
Can you extract B by combining the call stack and bytecode inside A.test?
You'll need to use the return address stored on the stack to locate the call to B.test in the bytecode and extract the declared call. There are plenty of bytecode manipulation libraries, but I don't know if any of them allow you to tie that to the execution stack in the JVM.
You can't override static methods in java.
http://geekexplains.blogspot.co.uk/2008/06/can-you-override-static-methods-in-java.html
Here's an example from Java. It uses Java 8 default methods and getClass(). I bet it works with classes too:
interface A {
default String name() {
return getClass().getName();
}
}
class B implements A {}
public class LateBinding {
public static void main(String[] args) {
// Create an anonymous class in `LateBinding` (called `$1`)
System.out.println(new A(){}.name());
// Instantiate a new `B`
B b = new B();
System.out.println(b.name());
}
}
Results:
$ javac LateBinding.java && java LateBinding
LateBinding$1
B
As you can see the method knows in both cases where it's running, although it's defined in A. This example is not really static, because you can't call getClass() statically, but LSB in PHP is not really limited to static contexts.
There is no elegant way to do it with static method declaration (Only Delphi from what I'm aware of supports override for static methods). However if static is not necessary for you you can write something like this:
class A {
public void who(){
System.out.println("A");
};
public void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
#Override
public void who(){
System.out.println("B");
};
public void main(String[] args){
A instance = new A();
instance.test(); // prints 'A'
instance = new B();
instance.test(); // prints 'B'
}
}
EDIT after clarification:
Pretty hacky way of doing this: Thread.currentThread().getStackTrace() then from top-most record get method and class this method belongs to. Having Class c - you could write c.getMethod("who").invoke(null); to call the correspond who() method.

Confusion about static keyword

I just read in a document that "A static method can call only other static methods and can not call a non-static method from it". But when I tried to test it I think saw something different.
I have a class C which is described below
import pckage1.*;
public class C
{
public static void main(String par[])
{
}
public static void cc()
{
A ob = new A();
ob.accessA(0);
}
}
where class A is
package pckage1;
public class A
{
public A()
{
}
public void accessA(int x)
{
}
}
Now here from cc STATIC method in class C, a NON STATIC method accessA() is called. How could that be possible if the statement about static method is true?
A static method can call only other static methods and can not call a non-static method from it
That's wrong.
Static methods can call non-static methods as long as they have objects to call the methods on (as you discovered in your code snippet). How else would a non-static method ever be called?
You can't do nonStaticFoo() from a static method, since it is interpreted as this.nonStaticFoo() and since there is no this available in a static method.
Very similar question from earlier today:
Static method access to non-static constructor?
You didn't call a non-static method of your Class.
Try with this :
import pckage1.*;
public class C
{
public static void main(String par[])
{
}
public static void cc()
{
A ob = new A();
ob.accessA(0);
print();
}
public void print()
{
}
}
It won't work, because you're callign a non-static method from a static method, and you don't have an instance of the C class to work with in your static method.
Since every Java program starts executing from a static method, if the statement you cite were true, there would have been no way for any Java program to ever execute an instance method!
A static method has no default context in C, and not this.
However any method can use an intsnace of a class to call a method.
You're calling an instance method, on an instance--you're not trying to call an instance method directly.
You're creating an instance of class A and call a method on it.
So the method you are calling is instance method (not static method).
But you cannot call a non static method of class C.

Categories