Java Reflection get only methods of subclass (without equals, hashcode etc) - java

Is there a way to get the methods of an Class object, without getting the methods defined by the Object class?
Right now I am using getDeclaredMethods() to look for a specific method with a list of parameters.
My problem is that this also returns functions like
"equals", "hashCode", etc...
and thus it could be ambiguous between these functions and the one I'm looking for.
Looking at the documentation, it says that it only returns the public methods defined by this class (or in my case an interface), and my objects never override these methods
Is there any workaround for this?
Example:
class Test implements ITest {
void myMethod() {...}
}
and in my code I have something like
Object o = new Test();
for (Method m : o.getClass().getDeclaredMethods()) {
System.out.println(m.getName()...);
}
and this prints me methods defined in the Object class

getMethods()returns all methods declared by a class, plus methods declared in the object class. You can use getDeclaredMethods() to access methods that are class specific or implemented from super class. Example:
interface IChild {
int child1(int a, int b);
}
static class ChildImpl implements IChild {
#Override
public int child1(int a, int b) {
return a*b;
}
public int child2(int x, int y){
return x+x*y;
}
}
public static void main(String[] args) {
IChild i=new ChildImpl();
System.out.println("===Non Object Methods===");
for(Method m:i.getClass().getDeclaredMethods()){
System.out.println("Declared Method"+m.getName());
}
System.out.println("===All Methods===");
for(Method m:i.getClass().getMethods()){
System.out.println("Method: "+m.getName());
}
}
}
Sample output:
===Non Object Methods===
Declared Method: child2
Declared Method: child1
===All Methods===
Method: child2
Method: child1
Method: wait
Method: wait
Method: wait
Method: equals
Method: toString
Method: hashCode
Method: getClass
Method: notify
Method: notifyAll

Related

Overriding method as varargs and Overridden method is normal method

public class DemoParent {
public void m1(int i) {
System.out.println("parent");
}
}
public class DemoChild extends DemoParent{
public void m1(int... i) {
System.out.println("child");
}
public static void main(String[] args) {
DemoParent p = new DemoChild();
p.m1(10);
DemoChild c = new DemoChild();
c.m1(10);
}
}
Here I have two class DemoParent and DemoChild which extends DemoParent, in DemoParent i have general method m1(int i) but in DemoChild i have varargs method m1(int... i). When i am creating object of child class and calling m1 method,it's giving me parent class method output. See below the output.
o/p- parent
parent
Can anyone explain me why parent class method is always calling from the Child class reference even if child has the same method?
but if we reverse the code i.e. parent class have varargs method and child has normal method then it will acts as an overloading instead of Overriding . So the output is
o/p - parent
child
but in the above 1st scenario i didn't understand why always parent class method is calling from child reference.
You're not overriding. You're overloading.
DemoChild has two methods called m1, and it has to choose which of the methods to invoke, based on the fact that you pass a single int as a parameter.
The non-varargs method will always be matched before the varargs overload, because the language spec rules around method invocation say that it will be (to preserve backwards compatibility with pre-varargs code).

Casting subclass to superclass and calling a function that both classes have

public class Test3 {
public static void main(String[] args) {
Derived04 b = new Derived04();
Base04 a = (Base04)b;
System.out.println(a.i);
System.out.println(a.f());
}
}
class Base04 {
int i=1;
public int f() {return i;}
}
class Derived04 extends Base04 {
int i = 2;
public int f(){return -i;}
}
Both classes include the f() method so when I cast d onto a which method does it go to when I call a.f()? I thinking since a is declared as Base04 type when you do a.i it gives 1 but then why does it use the method from the subclass?
The whole point is about implementing and casting. so when you create a Derived04 then you have implemented a Derived04 class, not its parents Base04 so even if you cast it like that it will run the implemented method not the casting method unless there is a different between f() in both classes. and that's not our case.
why does it use the method from the subclass?
You create an object of Derived04 class you just cast it to the type Base04. It is still Derived04 implementation.

Why it always invokes parent class method "doTest(double d)"? [duplicate]

This question already has answers here:
Polymorphism in Overloaded and Overridden Methods
(4 answers)
Closed 6 years ago.
class PolymorphisomTest {
class Base {
public void doTest(double d) {
System.out.println("From Base");
}
}
class DerivedBase extends Base {
public void doTest(int d) {
System.out.println("From Derived Base");
}
}
public void use(Base base) {
base.doTest(3);
}
public void run() {
use(new Base());
use(new DerivedBase ());
}
public static void main(String []cmd) {
new PolymorphisomTest ().run();
}
}
Here doTest(double d) from parent class and doTest(int d) from subclass but when i call base.doTest(3) it always invokes parent class method even my object reference is different. what's the reason behind it?
doTest(double d) is a completely different method from void doTest(int d), because they have different parameter lists. There actually isn't any polymorphism there at all; DerivedBase is declaring a new method, not overloading Base.doTest. It's as if you had done this:
class Base {
public void doTest(double d) {
System.out.println("From Base");
}
}
class DerivedBase extends Base {
public void doSomethingElse(int d) {
System.out.println("From Derived Base");
}
}
Changing a parameter's type changes the method signature, and makes it a new method instead of overriding the parent class' method.
When you call base.doTest(3), the compiler is going to call doTest(double), because that's the only method of the Base class that matches the parameter. Because that method isn't overriden by anything, Base.doTest gets called.
To override a method you must match the method signature in the derived class. When you change from double to int you create a new method. From Defining Methods - The Java Tutorials,
Definition: Two of the components of a method declaration comprise the method signature—the method's name and the parameter types.
The #Override annotation can protect you from this specific class of error. You can do something like,
class DerivedBase extends Base {
#Override
public void doTest(double d) {
System.out.println("From Derived Base");
}
}
DerivedBase class inherited your doTest from base class. Now, it has 2 methods-
doTest (double d)
doTest (int d)
You have not overridden method but overloaded it by giving different parameter. If you need to override doTest add method with double as parameter.
Reason why it is not calling doTest (int d) is when we call from parent reference , it searches for method their during compile time and bind with same. And at runtime , its same method with same signature from object in hand.

Polymorhism and the class Object

We know that each class extends from Object which means that we can use all Object's methods
in any class. My problem is the following:
interface B{
}
public class A implements B{
public static void main(String[] args){
B i = new A();
i.display();//we can't do this : because the interface B doesn't define such a method
System.out.println(i.toString());// we can do this although the interface doesn't extend from Object
}
public void display(){
}
}
so I think the problem is clear , why I could invoke the toString method although the interface B can't extend from Object?
This is spelled out in the JLS §9.2. Interface Members:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
This ensures that it is possible to call Object methods via any interface.

How to call function with same name from an inherited class in java

I am new to java and I remember in c++ we did something like CLASSNAME::Fn() to avoid ambiguity in inheritance.
Here's my code and I want to have same display methods in both classes and access them explicitly.
public class Main {
public static void main(String args[]){
Emplo e = new Emplo("samuel",19,"designer",465);
e.display(); // here i want to call both display()
}
}
public class Person {
String name;
int age;
Person(String s, int a){
name = s;
age = a;
}
public void dispaly(){
System.out.println("name: "+name+"\nage: "+age);
}
}
public class Emplo extends Person {
String desg;
double sal;
Emplo(String s,int a,String d, double sa){
super(s,a);
desg=d;
sal=sa;
}
void display(){
System.out.println("desg: "+desg+"\nsal: "+sal);
}
}
In java, you can't not call the specific method implementation of the class of the instance.
That is, you can't "bypass" a sub-class method and call a super-class version of the method; calling the super-class method can only be done from within the subclass using super.someMethod().
You can't even invoke a super-super class's version, ie you can't do something like super.super.someMethod()
First of in here you are use two different method. display() in Emplo and dispaly() in Person. SO there is no point of talking ambiguity or overriding make that correct.
Suppose you are corrected that. Then you can't code keep this way
public void display(){ // method in Person
System.out.println("name: "+name+"\nage: "+age);
}
Then
void display(){ // method in Emplo
System.out.println("desg: "+desg+"\nsal: "+sal);
}
You are using weaker modifier to override, So you can't compile this code. You can make public the method in Emplo.
And answer for your last question. you can't do it. can't call both method.
In the second display method call the super class display method by using super keywod as :
super.display(); (should be the first statement of the method)
and there will be no ambiguity because that display method will be called whose object is being created that means that the display() method of Employee will be called in this case
so if you want to call the display method of Person class then you should create the object of that class and reference by That class type like :
Person p = new Person(your data);
p.display() // here display method of person will be called
and No you cannot call both methods from the same reference
In your Emplo class display() method super.dispaly() indicates display() method of immediate super class i.e Person class.
void display(){ // here in Emplo class you can't give more restrictive modifier(i.e `public` to `default`. since in `Person` class it is `public` so it must be `public`.(overriding rule)
super.dispaly();
System.out.println("desg: "+desg+"\nsal: "+sal);
}
so put public modifier here:
public void display(){
super.dispaly();
System.out.println("desg: "+desg+"\nsal: "+sal);
}
`
Perhaps this answers your question:
public void myMethod()
{ //inherited method
super.myMethod(); //calls base class method
//... add more code to inherited method
}
for details see original source:
In Java, how do I call a base class's method from the overriding method in a derived class?

Categories

Resources