Class.getMethod in class's static initializer block

C

chucky

If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.

Example:

class A {
static Method m;

private static void method(String str) {
System.out.println(str);
}

static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}

This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?


Actually, I would like to write something like this:

class A {
private static void method(String str) {
System.out.println(str);
}
static Method m = A.method;
}

Of course, this code is invalid, but my idea is that the presence of
method is known at compile time, so I don't want the overhead of
reflection and I'd rather get a compilation error if there is no such
method. Something similar is possible with function pointers in C, but
is there sth. like that in Java?

Thanks for any help!
 
D

Daniel Pitts

chucky said:
If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.

Example:

class A {
static Method m;

private static void method(String str) {
System.out.println(str);
}

static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}

This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?


Actually, I would like to write something like this:

class A {
private static void method(String str) {
System.out.println(str);
}
static Method m = A.method;
}

Of course, this code is invalid, but my idea is that the presence of
method is known at compile time, so I don't want the overhead of
reflection and I'd rather get a compilation error if there is no such
method. Something similar is possible with function pointers in C, but
is there sth. like that in Java?

Thanks for any help!

Using reflection should be a last resort, and reserved for frameworks.
Have you considered creating a functor class? Something like the
following:

interface StringCall {
void call(String s);
}

class A {
private static void method(String b) {
System.out.println(b);
}

static StringCall call = new StringCall() { public call(String s)
{ method(s); } };
}

Perhaps if you explained your goal, rather than the approach you are
trying, we could offer you better advice.
 
A

A. Bolmarcich

If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.

Example:

class A {
static Method m;

private static void method(String str) {
System.out.println(str);
}

static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}

This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?
[snip]

It happens because according to the Java API documentation, getMethod:
"Returns a Method object that reflects the specified public member
method of the class or interface represented by this Class object."
Note the term "public member method".

Did you intend to invoke the getDelcaredMethod?
 
C

chucky

chucky said:
If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.

class A {
static Method m;
private static void method(String str) {
System.out.println(str);
}
static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}
This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?
Actually, I would like to write something like this:
class A {
private static void method(String str) {
System.out.println(str);
}
static Method m = A.method;
}
Of course, this code is invalid, but my idea is that the presence of
method is known at compile time, so I don't want the overhead of
reflection and I'd rather get a compilation error if there is no such
method. Something similar is possible with function pointers in C, but
is there sth. like that in Java?
Thanks for any help!

Using reflection should be a last resort, and reserved for frameworks.
Have you considered creating a functor class? Something like the
following:

interface StringCall {
void call(String s);

}

class A {
private static void method(String b) {
System.out.println(b);
}

static StringCall call = new StringCall() { public call(String s)
{ method(s); } };

}

Perhaps if you explained your goal, rather than the approach you are
trying, we could offer you better advice.

Thanks for your reply. I think I could do what I want with functors.

Here is what I want to do.
I have a code like this:

String str;

// some code

if(str.equals("string1")){ method1() }
else if(str.equals("string2")){ method2() }
else if(str.equals("string3")){ method3() }
....
// maybe 10-20 possibilities
....
else { /* default code */ }


And because I don't like it, I wanted to put each methodN() into a
static Map<String, Method> in static initializer.
Then I would change the above code into:

String str;

// some code

Method m = map.get(str);
if(m != null)
m.invoke();
else{ /* default code */ }


Some suggestions on this?

Many thanks in advance.
 
C

chucky

If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.

class A {
static Method m;
private static void method(String str) {
System.out.println(str);
}
static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}
This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?

[snip]

It happens because according to the Java API documentation, getMethod:
"Returns a Method object that reflects the specified public member
method of the class or interface represented by this Class object."
Note the term "public member method".

Did you intend to invoke the getDelcaredMethod?

You are right, getDeclaredMethod does not throw that exception.

Thanks!
 
D

Daniel Pitts

chucky said:
If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.
Example:
class A {
static Method m;
private static void method(String str) {
System.out.println(str);
}
static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}
This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?
Actually, I would like to write something like this:
class A {
private static void method(String str) {
System.out.println(str);
}
static Method m = A.method;
}
Of course, this code is invalid, but my idea is that the presence of
method is known at compile time, so I don't want the overhead of
reflection and I'd rather get a compilation error if there is no such
method. Something similar is possible with function pointers in C, but
is there sth. like that in Java?
Thanks for any help!
Using reflection should be a last resort, and reserved for frameworks.
Have you considered creating a functor class? Something like the
following:
interface StringCall {
void call(String s);

class A {
private static void method(String b) {
System.out.println(b);
}
static StringCall call = new StringCall() { public call(String s)
{ method(s); } };

Perhaps if you explained your goal, rather than the approach you are
trying, we could offer you better advice.

Thanks for your reply. I think I could do what I want with functors.

Here is what I want to do.
I have a code like this:

String str;

// some code

if(str.equals("string1")){ method1() }
else if(str.equals("string2")){ method2() }
else if(str.equals("string3")){ method3() }
...
// maybe 10-20 possibilities
...
else { /* default code */ }

And because I don't like it, I wanted to put each methodN() into a
static Map<String, Method> in static initializer.
Then I would change the above code into:

String str;

// some code

Method m = map.get(str);
if(m != null)
m.invoke();
else{ /* default code */ }

Some suggestions on this?

Many thanks in advance.

A couple of suggestions. One, is there something you could use that
isn't a string? int perhaps, or enum? The Map<String, Functor> is one
way to go, as your basically just replacing the switch construct.

If you do this in more than one place, you can add more methods to
your functor class.

I would add a default value too, instead of special null handling
everwhere:

public interface Something {
void foo();
void bar();
}

public class DefaultSomething implements Something {
public void foo() { /* default foo */ }
public void bar() { /* default bar */ }
}

public class SomethingLookup {
private Map<String, Something> somethings = new HashMap<String,
Something>();
Something defaultSomething = new DefaultSomething();
/* initialize somethings in constructor... */

public Something get(String somethingName) {
Something something = somethings.get(somethingName);
return (something == null) ? defaultSomething : something;
}
}


public class MyClass {
SomethingLookup lookup;
/* Iniitalize lookup in constructor */
public void foo(String name) {
lookup.get(name).foo();
}

public void bar(String name) {
lookup.get(name).bar();
}
}

You're Something implementations can be Fly Weights, so you can pass
any state information into the methods as another class. That way you
don't have to keep different SomethingLookup and Something objects for
every object that you wish to affect.
 
L

Lew

Daniel said:
chucky wrote:
If I call A.class.getMethod() from static initializer block of class
A, I get NoSuchMethodException.
Example:
class A {
static Method m;
private static void method(String str) {
System.out.println(str);
}
static {
try {
m = A.class.getMethod("method", new Class[] {String.class});
} catch(NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
}
This code always throws the ExceptionInInitializerError caused by
NoSuchMethodException.
Why does this happen?
Actually, I would like to write something like this:
class A {
private static void method(String str) {
System.out.println(str);
}
static Method m = A.method;
}
Of course, this code is invalid, but my idea is that the presence of
method is known at compile time, so I don't want the overhead of
reflection and I'd rather get a compilation error if there is no such
method. Something similar is possible with function pointers in C, but
is there sth. like that in Java?
Thanks for any help!
Using reflection should be a last resort, and reserved for frameworks.
Have you considered creating a functor class? Something like the
following:
interface StringCall {
void call(String s);
}
class A {
private static void method(String b) {
System.out.println(b);
}
static StringCall call = new StringCall() { public call(String s)
{ method(s); } };
}
Perhaps if you explained your goal, rather than the approach you are
trying, we could offer you better advice.
Thanks for your reply. I think I could do what I want with functors.

Here is what I want to do.
I have a code like this:

String str;

// some code

if(str.equals("string1")){ method1() }
else if(str.equals("string2")){ method2() }
else if(str.equals("string3")){ method3() }
...
// maybe 10-20 possibilities
...
else { /* default code */ }

And because I don't like it, I wanted to put each methodN() into a
static Map<String, Method> in static initializer.
Then I would change the above code into:

String str;

// some code

Method m = map.get(str);
if(m != null)
m.invoke();
else{ /* default code */ }

Some suggestions on this?

Many thanks in advance.

A couple of suggestions. One, is there something you could use that
isn't a string? int perhaps, or enum? The Map<String, Functor> is one
way to go, as your basically just replacing the switch construct.

If you do this in more than one place, you can add more methods to
your functor class.

I would add a default value too, instead of special null handling
everwhere:

public interface Something {
void foo();
void bar();
}

public class DefaultSomething implements Something {
public void foo() { /* default foo */ }
public void bar() { /* default bar */ }
}

public class SomethingLookup {
private Map<String, Something> somethings = new HashMap<String,
Something>();
Something defaultSomething = new DefaultSomething();
/* initialize somethings in constructor... */

public Something get(String somethingName) {
Something something = somethings.get(somethingName);
return (something == null) ? defaultSomething : something;
}
}


public class MyClass {
SomethingLookup lookup;
/* Iniitalize lookup in constructor */
public void foo(String name) {
lookup.get(name).foo();
}

public void bar(String name) {
lookup.get(name).bar();
}
}

You're Something implementations can be Fly Weights, so you can pass
any state information into the methods as another class. That way you
don't have to keep different SomethingLookup and Something objects for
every object that you wish to affect.

Besides calling it a "functor" approach, it's a "polymorphic" approach. The
value part of each map entry implements the functor interface (e.g., "void
invoke()") according to the logic called for by its key.

Some of the literature discusses polymorphism without mentioning functors, so
the additional search term should help find useful stuff.
 
C

chucky

Thank you for your prompt reply and elegant solution!
A couple of suggestions. One, is there something you could use that
isn't a string? int perhaps, or enum?

I think not, because that string comes from the 'outside
world' (viewed from my perspective). I was given someone else's code
that I'll have to deal with. I don't have access to this code at the
moment, I just remember that I wanted to think this out.
I'm almost sure that the application could be refactored so that it
uses enum instead of string, but that is behind my scope.

public class MyClass {
SomethingLookup lookup;
/* Iniitalize lookup in constructor */

I would still use
static SomethingLookup lookup;
and initialize it in static initializer block instead of constructor,
so that it is initialized once and not once per instance of MyClass.
Maybe you are discussing something related in the last paragraph,
which I didn't really catch on:( :
 
C

chucky

Besides calling it a "functor" approach, it's a "polymorphic" approach. The
value part of each map entry implements the functor interface (e.g., "void
invoke()") according to the logic called for by its key.

Some of the literature discusses polymorphism without mentioning functors, so
the additional search term should help find useful stuff.

Thank you for your remark.
Actually, I know (or should know, at least:)) what polymorphism is.
The problem was that I was not able to bring the theory into the
praxis, so I didn't find polymorphism as solution to my problem nor
did I recognized it in solution proposed by someone else.
 
M

Mark Space

chucky said:
Method m = map.get(str);
if(m != null)
m.invoke();
else{ /* default code */ }

You seem to have got the info you needed already. I just wanted to add
that I had some similar code for a "command line server" project. You
might find some good ideas in the code below, or I might get criticized
for language abuse. Either way it'll be educational for someone. ^_^



/*
* ServerTest.java
*
* Created on July 13, 2007, 4:28 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package servertest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io_OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author B
*/

/**
* Copyright 2007 All rights reserved.
*/

public class ServerTest implements Runnable
{
static private final boolean DEBUG = true;

public static void main(String[] args)
{
// TODO code application logic here
new Thread( new ServerTest() ).start();
}


// DEFAULT CONSTRUCTOR
/** Creates a new instance of ServerTest */
public ServerTest()
{
if( logger == null )
{
logger = Logger.getLogger( ServerTest.class.getName() );
if( DEBUG )
{
ConsoleHandler ch = new ConsoleHandler();
ch.setLevel( Level.ALL );
logger.addHandler( ch );
logger.setLevel( Level.ALL );
logger.setUseParentHandlers( false );
}
}
// port = 25; // 25 is telnet port #
port = 4040;
runServer = true;
commandList = new HashMap<String, CommandLine>();
addCommand( new QuitLineCommand() );
addCommand( new HelloLineCommand() );
addCommand( new ErrorLineCommand() );
addCommand( new TestLineCommand( "test", new CommandRunner()
{ public ReturnCode runCommand( String s )
{ return (ReturnCode) new TestReturnCode( 0, false, "Test
succeded." ); }} ));
}

public void addCommand( CommandLine cl )
{
commandList.put( cl.getCommand(), cl );
}

public void run()
{
while( runServer )
{
try
{
ServerSocket sock = new ServerSocket( port );
logger.info( "Accepting connections on port " + port );
// System.err.println( "Accepting connections on port " +
port );

Socket client = sock.accept();

InputStream clientInput = client.getInputStream();
OutputStream clientOutput = client.getOutputStream();

PrintWriter clientPW = new PrintWriter( clientOutput,
true );
BufferedReader clientBR = new BufferedReader( new
InputStreamReader( clientInput ) );

while( true )
{
String line = clientBR.readLine();
// System.err.println( line );
logger.finer( line );
if( line.length() == 0 )
{
continue;
}
String commands [] = line.split( ":", 2 );
// System.err.print( commands.length + " commands " );
logger.log( Level.FINEST, "Split commands are ",
commands );
// for( int i = 0; i < commands.length; i++ )
// {
// System.err.print( commands + ", " );
// }
// System.err.println();

CommandLine exeObj = null;
if( commands.length >= 1 )
{
exeObj = commandList.get( commands[0] );
}
if( exeObj != null )
{
// System.err.println( exeObj );
String arguments = null;
if( commands.length > 1 )
{
arguments = commands[1];
}
ReturnCode rc = exeObj.runCommand( commands[0],
arguments );
if( rc == null )
{
// System.err.println( "return object was
null!" );
logger.warning( "Return object was null!" );
continue;
}
if( rc.isError() )
{
clientPW.print( '\07' ); // ASCII bell
}
if( rc.getCode() != 0 )
{
clientPW.print( "(" + rc.getCode() +")" );

}
if( rc.getMessage() != null )
{
clientPW.print( rc.getMessage() );
}
clientPW.println();
if( rc.getCode() == -1 )
{
runServer = false;
break;
}
}
else
{
clientPW.println( "\07Command not found." );
// \07 is ASCII bell
// clientPW.flush();
}
}

}
catch (IOException ex)
{
ex.printStackTrace();
}

}

}


private int port;
private boolean runServer;
private Map<String, CommandLine> commandList;
private static Logger logger;
}

class LineParser
{
public boolean addCommand( CommandLine c )
{
//...
return true;
}

public ReturnCode parseLine( String line )
{
ReturnCode rc = null;
//...
return rc;
}
}

interface CommandLine
{
// public CommandLine( String command );
public String getCommand();
public ReturnCode runCommand( String command, String args );
}

interface CommandRunner
{
public ReturnCode runCommand( String args );
}

class TestLineCommand implements CommandLine
{
public TestLineCommand( String command, CommandRunner exec )
{
this.command = command;
this.exec = exec;
}

public String getCommand()
{
return command;
}

public ReturnCode runCommand(String command, String args)
{
return exec.runCommand( args );
}

private String command;
private CommandRunner exec;
}
class QuitLineCommand implements CommandLine
{
public String getCommand()
{
return "quit";
}

public ReturnCode runCommand(String command, String args)
{
return (ReturnCode) new TestReturnCode( -1, false, "Good-bye" );
}
}

class ErrorLineCommand implements CommandLine
{
public String getCommand()
{
return "error";
}

public ReturnCode runCommand(String command, String args)
{
return (ReturnCode) new TestReturnCode( 1, true, args );
}

}

class HelloLineCommand implements CommandLine
{
public String getCommand()
{
return "hello";
}

public ReturnCode runCommand( String command, String args )
{
return (ReturnCode) new TestReturnCode( 0, false, "Hello World!
You typed: " + args );
}
}

interface ReturnCode
{
public int getCode();
public boolean isError();
public String getMessage();
// public String getExtendedMesage();
}

class TestReturnCode implements ReturnCode
{
public TestReturnCode( int code, boolean isError, String message )
{
this.code = code;
this.error = isError;
this.message = message;
}

public int getCode()
{
return code;
}

public boolean isError()
{
return error;
}

public String getMessage()
{
return message;
}

private int code;
private boolean error;
private String message;
}
 
T

Twisted

Actually, I know (or should know, at least:)) what polymorphism is.
The problem was that I was not able to bring the theory into the
praxis, so I didn't find polymorphism as solution to my problem nor
did I recognized it in solution proposed by someone else.

Praxis? Isn't that that Klingon moon that exploded back in the
nineties?
 
T

Twisted

all of it ;) it is also a German word (Praxis)

Pale imitations! You cannot really appreciate this fine literature
until you've read it in the original Klingon.
 

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

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top