I know, there is already at least one question on this topic. But I want to ask it again because this is what I discovered in the javadoc of Class#getDeclaredMethod(...)
:
If more than one method with the same parameter types is declared in a class, and one of these methods has a return type that is more specific than any of the others, that method is returned; otherwise one of the methods is chosen arbitrarily.
So the developers of the reflection in java consider that case as a probable one, is it maybe possible after all to do such declaration? Or is it maybe just deprecated?
Yes, we can define multiple methods in a class with the same name but with different types of parameters.
If a class has multiple methods having same name but different in parameters, it is known as Method Overloading.
You cannot declare more than one method with the same name and the same number and type of arguments, because the compiler cannot tell them apart. The compiler does not consider return type when differentiating methods, so you cannot declare two methods with the same signature even if they have a different return type.
Explanation: Function overloading is a process of defining more than one method in a class with same name differentiated by function signature i:e return type or parameters type and number. Example – int volume(int length, int width) & int volume(int length , int width , int height) can be used to calculate volume.
The JVM bytecode format permits the declaration of multiple methods with the same name and the same parameter types as long as the return type differs, although the Java language does not permit this. This means a) other JVM languages can make use of this and b) it can be used for special "compiler-magic" language features.
Most commonly, the compiler emits multiple methods with the same name and the same parameter types when dealing with generics. JVM method lookup relies on the entire signature to match, not just the parameter types. Thus, the compiler has to emit so-called bridge
methods that override or shadow other methods signature-wise. Consider this example:
interface Foo<T>
{
T foo(); // desc: ()Ljava/lang/Object;
void bar(T value); // desc: (Ljava/lang/Object;)V
Object baz(); // desc: ()Ljava/lang/Object;
}
class StringFoo implements Foo<String>
{
@Override
public String foo() { ... } // desc: ()Ljava/lang/String; // !
@Override
public void bar(String value) { ... } // desc: (Ljava/lang/String;)V // !
@Override
public String baz() { ... } // desc: ()Ljava/lang/String; // !
}
The StringFoo
class needs three additional bridge methods to actually override the interface methods in terms of having the same desc
:
class StringFoo implements Foo<String>
{
public String foo() { ... }
public /* synthetic bridge */ Object foo() // desc: ()Ljava/lang/Object;
{
return /* String */ foo(); // statically linked to String foo()
}
public void bar(String value) { ... }
public /* synthetic bridge */ void bar(Object value) // desc: (Ljava/lang/Object;)
{
return bar((String) value);
}
public String baz() { ... }
public /* synthetic bridge */ Object baz() // desc: ()Ljava/lang/Object;
{
return /* String */ baz(); // statically linked to String baz()
}
}
The pseudo-modifiers synthetic bridge
are two JVM access flags that are only used by the compiler to mark auto-generated methods in the bytecode
The Class#getDeclaredMethods
method returns all declared methods - including synthetic bridge methods. Thus, #getDeclaredMethod(String)
has to pick one that is the actual implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With