Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2007

Tip: Looking for answers? Try searching our database.

Class.getMethod in class's static initializer block

Thread view: 
chucky - 01 Aug 2007 19:19 GMT
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!
Daniel Pitts - 01 Aug 2007 19:27 GMT
> If I call A.class.getMethod() from static initializer block of class
> A, I get NoSuchMethodException.
[quoted text clipped - 37 lines]
>
> 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.
chucky - 01 Aug 2007 20:07 GMT
> > If I call A.class.getMethod() from static initializer block of class
> > A, I get NoSuchMethodException.
[quoted text clipped - 59 lines]
> 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.
Daniel Pitts - 01 Aug 2007 20:59 GMT
> > > If I call A.class.getMethod() from static initializer block of class
> > > A, I get NoSuchMethodException.
[quoted text clipped - 93 lines]
>
> 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.
Lew - 01 Aug 2007 21:13 GMT
>>>> If I call A.class.getMethod() from static initializer block of class
>>>> A, I get NoSuchMethodException.
[quoted text clipped - 125 lines]
> 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.

Signature

Lew

chucky - 01 Aug 2007 22:11 GMT
> 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
[quoted text clipped - 5 lines]
> --
> Lew

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.
Twisted - 02 Aug 2007 01:19 GMT
> 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?
chucky - 02 Aug 2007 10:16 GMT
> Praxis? Isn't that that Klingon moon that exploded back in the
> nineties?

:-)
Sorry, praxis is Latin. Practice is the right word?
Ingo Menger - 02 Aug 2007 10:23 GMT
> > Praxis? Isn't that that Klingon moon that exploded back in the
> > nineties?
>
> :-)
> Sorry, praxis is Latin. Practice is the right word?

I'd bet it's Greek.
Tim Hemig - 02 Aug 2007 10:28 GMT
>> > Praxis? Isn't that that Klingon moon that exploded back in the
>> > nineties?
[quoted text clipped - 3 lines]
>
> I'd bet it's Greek.

all of it ;) it is also a German word (Praxis)
Twisted - 02 Aug 2007 13:22 GMT
> >> > Praxis? Isn't that that Klingon moon that exploded back in the
> >> > nineties?
[quoted text clipped - 5 lines]
>
> 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.
chucky - 01 Aug 2007 21:56 GMT
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:( :

> 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.
Mark Space - 01 Aug 2007 22:44 GMT
> 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[i] + ", " );
//                    }
//                    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;
}
A. Bolmarcich - 01 Aug 2007 19:34 GMT
> If I call A.class.getMethod() from static initializer block of class
> A, I get NoSuchMethodException.
[quoted text clipped - 20 lines]
> 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?
chucky - 01 Aug 2007 20:08 GMT
On Aug 1, 8:34 pm, "A. Bolmarcich" <agge...@earl-grey.cloud9.net>
wrote:

> > If I call A.class.getMethod() from static initializer block of class
> > A, I get NoSuchMethodException.
[quoted text clipped - 29 lines]
>
> Did you intend to invoke the getDelcaredMethod?

You are right, getDeclaredMethod does not throw that exception.

Thanks!


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.