Method calling

G

gaijinco

Is there a way in Java to call a method by having its name on a
string?

something as:

void foo(){}
void bar(){}

void callFunction(String s)
{
// Call function s
}

void otherFunction()
{
callFunction("foo");
}

Thanks.
 
T

Tom Anderson


This has pretty much nothing to do with what the OP wants to do.

That document weirds me out, actually. Beans are something i associate
with early java, around 1.1 or something - it's an idea that never really
went anywhere. The fact that support was dropped from NetBeans 6 is
telling. And yet someone's gone to the trouble of updating it to use
new-style for loops!

tom
 
G

gaijinco

Thanks Steve and Seamus for your quick responses.

I checked the API and I got a prototype running very quickly.

There's only just I question remaining: In the API Class is not a raw
type, it's parametized. However if I try to do this:

TestClass t = new TestClass();
Class<TestClass> c = t.getClass();

Eclipse's compiler complains:

Type mismatch: cannot convert from Class<capture#1-of ? extends
TestClass> to Class<TestClass>

What's the deal with that?

Thanks again!
 
A

Arne Vajhøj

gaijinco said:
Is there a way in Java to call a method by having its name on a
string?

something as:

void foo(){}
void bar(){}

void callFunction(String s)
{
// Call function s
}

void otherFunction()
{
callFunction("foo");
}

You can use reflection.

See example below.

Arne

============================================

import java.lang.reflect.*;

public class Refl2 {
public void m1(String a, String b) {
System.out.println("m1: " + a + " " + b);
}
public void m2(String a, String b) {
System.out.println("m2: " + a + " " + b);
}
public static void c(Object o, String methodName, String a, String b) {
try {
Class declarg[] = new Class[2];
declarg[0] = String.class;
declarg[1] = String.class;
Method m = o.getClass().getMethod(methodName, declarg);
Object callarg[] = new Object[2];
callarg[0] = a;
callarg[1] = b;
m.invoke(o, callarg);
} catch (Exception e) {
}
}
public static void main(String[] args) {
Refl2 r = new Refl2();
r.m1("a", "b");
r.m2("a", "b");
c(r, "m1","a", "b");
c(r, "m2","a", "b");
}
}
 
T

Tom Anderson

Thanks Steve and Seamus for your quick responses.

I checked the API and I got a prototype running very quickly.

There's only just I question remaining: In the API Class is not a raw
type, it's parametized. However if I try to do this:

TestClass t = new TestClass();
Class<TestClass> c = t.getClass();

Eclipse's compiler complains:

Type mismatch: cannot convert from Class<capture#1-of ? extends
TestClass> to Class<TestClass>

What's the deal with that?

It's because when you have a variable of type TestClass, it could contain
an instance of TestClass, or of a subclass of TestClass. So, your Class
could be a Class<TestClass>, or it could be a Class<a subclass of
TestClass> - and in formal generics language, that's Class<? extends
TestClass>.

To get an exact Class, do it statically, with a class literal:

Class<TestClass> cl = TestClass.class ;

You could do this, though:

Class<? extends TestClass> cl = t.getClass() ;

You can do pretty much the same things with a Class<? extends TestClass>
as a Class<TestClass>. More or less. Probably.

tom
 
D

Daniel Pitts

Tom said:
This has pretty much nothing to do with what the OP wants to do.

That document weirds me out, actually. Beans are something i associate
with early java, around 1.1 or something - it's an idea that never
really went anywhere. The fact that support was dropped from NetBeans 6
is telling. And yet someone's gone to the trouble of updating it to use
new-style for loops!

tom
Except that JavaBeans are used all over the place. J2EE containers,
Spring Framework, Hibernate, to name but a few. Even most of the awt and
Swing use JavaBeans.
 
D

Daniel Pitts

gaijinco said:
Is there a way in Java to call a method by having its name on a
string?

something as:

void foo(){}
void bar(){}

void callFunction(String s)
{
// Call function s
}

void otherFunction()
{
callFunction("foo");
}

Thanks.
The real question is why?

The technique you want is called reflection. It is often better to not
use reflection, unless you have a "Damned Good Reason".
<http://virtualinfinity.net/wordpres...angers-of-reflection-or-put-down-that-mirror/>

That being said. You can do something like:
myClass.class.getMethod("foo").invoke(this);

Instead of using "by name", you might think about using a pattern like:

void foo() {}
void bar() {}

void callFunction(Runnable r) { r.run(); }

void otherFunction() {
callFunction(new Runnable() { public void run() { foo(); } });
}

Yes, this is a little more typing, but the benefit is that you *can't*
misspell "foo" (the compiler wouldn't let you). There may be even
better ways to solve your real problem. What is your real goal?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top