Call method of unknown object

python intercept method call
python unknown method
python3 call method by string
python catchall method
python redirect function call
python dynamic function call
python dynamically call method name
how private method can be called using reflection

I have two ArrayLists - ArrayList1 and ArrayList2. Each of them is filled with objects - Object1 and Object2, respectively. Both of these objects have method 'getText'.

Object1:

public String getText() { return "1";}

Object2:

public String getText() { return "2";}

At certain point I would like to loop through each of these lists using the same method (just with different parameter).

loopThroughList(1)
loopThroughList(2)

What is the syntax if I want to call a method, but I don't know which object it is going to be? This is the code I have so far:

for (Object o : lists.getList(listNumber)) {
    System.out.println(o.getText());
}

It says Cannot resolve method getText. I googled around and found another solution:

for (Object o : lists.getList(listNumber)) {
    System.out.println(o.getClass().getMethod("getText"));
}

But this gives me NoSuchMethodException error. Even though the 'getText' method is public.

EDIT: To get the correct list, I am calling the method 'getList' of a different object (lists) that returns either ArrayList1 or ArrayList2 (depending on the provided parameter).

class Lists

public getList(list) {
    if (list == 1) {
        return ArrayList1;
    }
    else if (list == 2) {
        return ArrayList2;
    }
}

Define an interface for the getText method

public interface YourInterface {

    String getText();     

}

Implement the interface on the respective classes

public class Object1 implements YourInterface {

    @Override
    public String getText() { 
        return "1";
    }

}

public class Object2 implements YourInterface {

    @Override
    public String getText() { 
        return "2";
    }

}

Modify your getList method to return List<YourInterface>

public static List<YourInterface> getList(int list){
    List<YourInterface> result = new ArrayList<>();
    if(list == 1){
        // your initial type
         List<Object1> firstList = new ArrayList<>();
         result.addAll(firstList);
    } else {
        // your initial type
        List<Object2> secondList = new ArrayList<>();
        result.addAll(secondList);
    }
    return result;
}

Declaration for loopThroughList

public static void loopThroughList(List<YourInterface> list){
    list.forEach(yourInterface -> System.out.println(yourInterface.getText()));
}

Sample usage.

public static void main(String[] args) {
    loopThroughList(getList(1));
    loopThroughList(getList(2));
}

This object has 3 methods, and asks the user to name one to call. Instead of using Func(), one could use a class definition. obj := {mA: Func(  To call factory methods of objects of an unknown type (such as when you may have a subclass of the class wanted), it is necessary to get a reference to the class's factory object by calling the "FactoryObject" method. INVOKE foo-instance "FactoryObject" RETURNING foo-factory.

Interfaces work great here, but there a couple of other options if you're dealing with legacy code and cannot use interfaces.

First would be to cast the list items into their respective types:

for (Object o : lists.getList(listNumber)) {
    if(o instanceof Object1) {
        Object1 o1 = (Object1)o;
        System.out.println(o1.getText());
    }
    else if(o instanceof Object2) {
        Object1 o2 = (Object2)o;
        System.out.println(o2.getText());
    }
    else {
        System.out.println("Unknown class");
    }
}

You can also use reflection to see if the object has a getText method and then invoke it:

for (Object o : lists.getList(listNumber)) {
    try {
        System.out.println(o.getClass().getDeclaredMethod("getName").invoke(o));
    }
    catch(Exception e) {
        System.out.println("Object doesn't have getText method");
    }
}

Demonstrate how to make the object respond (sensibly/usefully) to an invocation of a method on it that it does not support through its  Unknown methods are called just like any other function. Find the method-naming symbol using INTERN then call it with FUNCALL. (funcall (intern "SOME-METHOD") my-object a few arguments) Déjà Vu local :object { :add @+ } local :method :add !. object! method 1 2

This is awful. Can you elaborate on what specifically you are trying to do? Java is strong typed by design, and you are trying to get around it. Why? Instead of Object, use the specific class, or interface as previously suggested. If that's not possible, and you must use lists of Objects, use instanceof and casting eg:

for (Object o : lists.getList(listNumber)) {
    if (o instanceof Object1) {
        Object1 o1 = (Object1) o;
        System.out.println(o1.getText());
    } else if (o instanceof Object2) {
        Object2 o2 = (Object2) o;
        System.out.println(o2.getText());
    }
}

The first, called Game_Events , controls the objects and manages the general tasks. The second, called Button , is for one of those object  In fact, I am writing a simulator program and a person who uses my program will write a class with some methods (and defines some attributes for each method) and in run-time, I compile the code and obtain the information about each method and then, call some of those methods. – Ali Khalili Jan 8 '12 at 23:26

This is where interfaces come in.

interface HasText {
    public String getText();
}

class Object1 implements HasText {
    @Override
    public String getText() {
        return "1";
    }
}

class Object2 implements HasText {
    @Override
    public String getText() {
        return "2";
    }
}

private void test() {
    List<HasText> list = Arrays.asList(new Object1(), new Object2());
    for (HasText ht : list) {
        System.out.println(ht);
    }
}

If one of your objects is not in your control you can use a Wrapper class.

class Object3DoesNotImplementHasText {
    public String getText() {
        return "3";
    }
}

class Object3Wrapper implements HasText{
    final Object3DoesNotImplementHasText it;

    public Object3Wrapper(Object3DoesNotImplementHasText it) {
        this.it = it;
    }

    @Override
    public String getText() {
        return it.getText();
    }
}

private void test() {
    List<HasText> list = Arrays.asList(new Object1(), new Object2(), new Object3Wrapper(new Object3DoesNotImplementHasText()));
    for (HasText ht : list) {
        System.out.println(ht);
    }
}

cs" which holds the basics for the player to interact with certain game objects. When added to a game object, the player can press E while inside  In order to call method, you need to create object of containing class, then followed bydot(.) operator you can call the method. If method is static, then there is no need to create object and you can directly call it followed by class name.

Just to add more to this answer and give you some more to think on this (Will try to do it in a simple, non-formal way). Using interfaces is the proper way of doing such operation. However, I want to stand on the "bad idea":

for (Object o : lists.getList(listNumber)) {
    System.out.println(o.getClass().getMethod("getText"));
}

What you are doing here, is using a mechanism called Reflection:

Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.

What you actually attempted, is using that mechanism, to retrieve the method through a Class reflection object instance of your Class (sounds weird, isn't it?).

From that perspective, you need to think that, if you want to invoke your method, you now have, in a sense, a meta-Class instance to manipulate your objects. Think of it like an Object that is one step above your Objects (Similarly to a dream inside a dream, in Inception). In that sense, you need to retrieve the method, and then invoke it in a different (meta-like) way:

java.lang.reflect.Method m = o.getClass().getMethod("getText");
m.invoke(o);

Using that logic, you could possibly iterate through the object list, check if method exists, then invoke your method.

This is though a bad, BAD idea.

Why? Well, the answer relies on reflection itself: reflection is directly associated with runtime - i.e. when the program executes, practically doing all things at runtime, bypassing the compilation world.

In other words, by doing this, you are bypassing the compilation error mechanism of Java, allowing such errors happen in runtime. This can lead to unstable behavior of the program while executing - apart from the performance overhead using Reflection, which will not analyze here.

Side note: While using reflection will require the usage of Checked Exception handling, it still is not a good idea of doing this - as you practically try to duck tape a bad solution.

On the other hand, you can follow the Inheritance mechanism of Java through Classes and Interfaces - define an interface with your method (let's call it Textable), make sure that your classes implement it, and then use it as your base object in your list declaration (@alexrolea has implemented this in his answer, as also @OldCurmudgeon has).

This way, your program will still make the method call decision making at Runtime (via a mechanism called late binding), but you will not bypass the compilation error mechanism of Java. Think about it: what would happen if you define a Textable implementation without providing the class - a compile error! And what if you set a non-Textable object into the list of Textables? Guess what! A compile error again. And the list goes on....

In general, avoid using Reflection when you are able to do so. Reflection is useful in some cases that you need to handle your program in such a meta-way and there is no other way of making such things. This is not the case though.

UPDATE: As suggested by some answers, you can use instanceof to check if you have a specific Class object instance that contains your method, then invoke respectively. While this seems a simple solution, it is bad in terms of scaling: what if you have 1000 different classes that implement the same method you want to call?

invoke() . The first argument is the object instance on which this particular method is to be invoked. (If the method is static , the first argument should  The call () allows for a function/method belonging to one object to be assigned and called for a different object. call () provides a new value of this to the function/method. With call (), you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.

First, we need to get a Method object that reflects the method we want to invoke. The Class object, representing the type in which the method is  Method Description; IUnknown::AddRef: Increments the reference count for an interface pointer to a COM object. You should call this method whenever you make a copy of an interface pointer. IUnknown::QueryInterface: Retrieves pointers to the supported interfaces on an object. IUnknown::QueryInterface

Collection<String> is not a subtype of Collection<Object> do not know what objects comply to that unknown subtype of E . In return for this limitation, The latter is called contravariance, and you can only call methods that take String as an  The class_name here is dynamic, the value is passed by other program. so the methods of the different class_name are dynamic as well. that is why we can not use create object obj type class_name here.

Static, null, null, new Object[] { stringParam }); // Return the string that was returned by the called method. return s; }. When you call this version, pass a string in  This is a convenience method that calls the Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) method overload, passing Default for invokeAttr and null for binder and culture. If the invoked method throws an exception, the Exception.GetBaseException method returns the exception.

Comments
  • Create an interface that declares the getText() method, have both your objects implement it, then declare your list as a List<NameOfTheInterface> . That way you can do for (NameOfTheInterface o : lists.getList(listNumber)) and call o.getText() .
  • How is declared lists ?
  • Can you please elaborate on the declaration of loopThroughList, taking into account the edit of the original question?
  • loopThroughList should accept objects of type ArrayList<Object1> or ArrayList<Object2>, considering both Object1 and Object2 implement YourInterface.
  • Could you provide the implementation for getList in your question?
  • I suppose you have ArrayList<Object1> and ArrayList<Object2>, not two different types of ArrayList, right?
  • @JanHorčička Updated answer
  • In which class file do I define the interface?
  • @JanHorčička - Anywhere really ... it depends where you want to use them.
  • in a seperate one, create a new HasText.java file with public interface inside.
  • I used your solution, but it doesn't work. I created an interface and made the two classes implement it (as it is in your code). The error message is still the same. Maybe the reason is that I am getting the correct list from another object (see edit in the original post).
  • @JanHorčička I have added the wrapper trick to wrap objects that do not implement your interface.