Getting information about children

Discussion in 'Java' started by Eric, Aug 24, 2005.

  1. Eric

    Eric Guest

    Hi all,

    I've been trying to get my mind around a certain setup, and am sure I'm
    missing something. I was hoping someone could shed some light on it.

    Say you had a simple library type application, and you set it up so
    that all books would be children of a Book superclass:

    public class Book {}

    public class Philosophy extends Book {
    static int DeweyDecimal = 601;
    }

    public class JavaProgramming extends Book {
    static int DeweyDecimal = 005;
    }

    public class WebstersDictionary extends Book {
    static int DeweyDecimal = 903;
    }

    Now, if I had an array I'd created off all the classes of books (e.g.
    Book[] books = {Philosophy.class, JavaProgramming.class,
    WebstersDictionary.class}) how would I go about getting the
    DeweyDecimal number of one of the types of books without instantiating
    them?

    I'd be happy to do so through a method, or add anything to the parent
    class, but although I've looked at reflection and thought about it a
    fair bit, I haven't been able to figure out a way to do this...

    Any thoughts? :)

    Eric
     
    Eric, Aug 24, 2005
    #1
    1. Advertisements

  2. Eric

    klynn47 Guest

    Are you using 1.5?
     
    klynn47, Aug 24, 2005
    #2
    1. Advertisements

  3. Eric

    Eric Guest

    I'm currently using 1.4.2, but would grudgingly update if 1.5 provides
    a clean solution to this.

    Thanks,

    Eric
     
    Eric, Aug 24, 2005
    #3
  4. Eric

    Roedy Green Guest


    You could use something like BCEL to analyse the class files and
    extract the info, but that seems one heck of a lot of work.
    see http://mindprod.com/jgloss/jasm.html
    for the link to BCEL.

    Another way entirely to get it is to write a little regex that chases
    through the source code extracting the needed numbers.

    You can get the numbers without instantiating, but with loading the
    classes with code something like this:

    int[] numbers = { Philosophy.deweyDecimal, Java.deweyDecimal ... };

    If you make deweyDecimal a static final, I suspect that code might
    even get them without loading the classes.

    Do a Java -verbose to be sure.

    If you defined an interface Dewey with an instance method called
    getDeweyDecimal, and all your classes implement it, then you could say
    something like this:


    for ( String className : classNames )
    {
    Class dynamicallyLoadedClass = Class.forName( com.yourdomain.books."
    + className );
    Dewey d = (Dewey)( dynamicallyLoadedClass.newInstance() );
    int number = d.getDeweyDecimal();
    }

    code is off the top of my head. For more detail see
    http://mindprod.com/jgloss/classforname.html
     
    Roedy Green, Aug 24, 2005
    #4
  5. ^^^^^^In general a static variable should also be final.
    Generally this sort of hiding is a bad idea.
    That array doesn't make any sense. Book[] is an array of books.
    Class<Book>[] is an array of book types.

    If you just need to find the DeweyDecimal number for a given book,
    either add an abstract method to the Book base class and override, or
    pass the number through the constructor.

    If you need to manipulate types of book, it is far better to introduce a
    type for the type of book rather than attempt to botch something up with
    Classes and reflection. Something like (in 5.0):

    /** @see Book */
    enum BookType {
    PHILOSOPHY(601) {
    public Philosophy create() {
    return new Philosophy();
    }
    },
    JAVA_PROGRAMMING(5) {
    public JavaProgramming create() {
    return new JavaProgramming();
    }
    },
    WEBSTER_DICTIONARY(903) {
    public WebstersDictionary create() {
    return new WebstersDictionary();
    }
    },
    ;
    private final int deweyDecimal;
    private BookType(int deweyDecimal) {
    this.deweyDecimal = deweyDecimal;
    }
    public final int getDeweyDecimal() {
    return deweyDecimal;
    }
    public abstract Book create();
    }

    Not the problem with Dewey Decimal representation differing from Java
    ints. Possibly you may want to use a different type.

    Tom Hawtin
     
    Thomas Hawtin, Aug 24, 2005
    #5
  6. Hi,
    First: your books-array will cause a compiler error. It must be one of
    the following:

    Class[] books = {Philosophy.class, JavaProgramming.class,
    WebstersDictionary.class}

    or

    Books[] books={new Philiosopy(), new ...}

    To your question: When using the first version, nothing is instantiated.
    You can use Reflection (java.lang.reflect.*) for reading the
    int-variables. Since those variables are static, you do dot need to
    instantiate the classes.

    Ciao,
    Ingo
     
    Ingo R. Homann, Aug 24, 2005
    #6
  7. Eric

    Eric Guest

    Hi Roedy,

    Will have a look at BCEL, thanks for the pointer.

    WRT the numbers array, I was trying to avoid exactly this issue, where
    there are multiple arrays that have information about the classes and
    each needs to be updated whenever a new class is added. It seems
    cludgy and errorprone. Instead I'd love to able to just drop in a new
    class of the appropriate type, and immediately be able to extract the
    needed info from it (referring to the libary example, to be able to add
    a new book, and have the application extract information such as the
    dewey decimal number without being explicitly told).

    The example code you provide instantiates each class which is what I
    was hoping to avoid.

    Thanks again for your reply and the info,

    John
     
    Eric, Aug 25, 2005
    #7
  8. Eric

    Eric Guest

    Good point about the static variable, I just wrote up the example code
    of the top of my head, but you're certainly correct. I got the type of
    the array wrong too, thanks for catching it.

    The problem with an overridden abstract method is that I'd need to
    instantiate the class to use it :-(. That ideally would have been my
    approach, an abstract static method, but I don't think Java allows such
    a beast.

    The enum in 1.5 looks like it might be worth upgrading for.

    Thanks!

    Cliff
     
    Eric, Aug 25, 2005
    #8
  9. Eric

    Eric Guest

    Hi Roedy,

    Will have a look at BCEL, thanks for the pointer.

    WRT the numbers array, I was trying to avoid exactly this issue, where
    there are multiple arrays that have information about the classes and
    each needs to be updated whenever a new class is added. It seems
    cludgy and errorprone. Instead I'd love to able to just drop in a new
    class of the appropriate type, and immediately be able to extract the
    needed info from it (referring to the libary example, to be able to add
    a new book, and have the application extract information such as the
    dewey decimal number without being explicitly told).

    The example code you provide instantiates each class which is what I
    was hoping to avoid.

    Thanks again for your reply and the info,

    Cliff
     
    Eric, Aug 25, 2005
    #9
  10. Eric

    Eric Guest

    Good point about the static variable, I just wrote up the example code
    of the top of my head, but you're certainly correct. I got the type of
    the array wrong too, thanks for catching it.

    The problem with an overridden abstract method is that I'd need to
    instantiate the class to use it :-(. That ideally would have been my
    approach, an abstract static method, but I don't think Java allows such
    a beast.

    The enum in 1.5 looks like it might be worth upgrading for.

    Thanks!

    Eric
     
    Eric, Aug 25, 2005
    #10
  11. Eric

    Eric Guest

    Hi Roedy,

    Will have a look at BCEL, thanks for the pointer.

    WRT the numbers array, I was trying to avoid exactly this issue, where
    there are multiple arrays that have information about the classes and
    each needs to be updated whenever a new class is added. It seems
    cludgy and errorprone. Instead I'd love to able to just drop in a new
    class of the appropriate type, and immediately be able to extract the
    needed info from it (referring to the libary example, to be able to add
    a new book, and have the application extract information such as the
    dewey decimal number without being explicitly told).

    The example code you provide instantiates each class which is what I
    was hoping to avoid.

    Thanks again for your reply and the info,

    Eric
     
    Eric, Aug 25, 2005
    #11
  12. Eric

    Eric Guest

    Hi Ingo,

    Sorry about my earlier error, I'd prefer to use the Class[] books
    array. Given the below code, how would I go about reading the values
    of the int-variables? I looked at java.lang.reflect.*, but all
    relevant methods seem to require an Object.

    Thanks so much for your time.

    ---

    public class BookTest {
    public static void main(String[] args) {
    Class[] books = new Class[]{Philosophy.class,
    JavaProgramming.class, WebstersDictionary.class};
    // use reflection here
    }
    }


    class Book {
    }


    class Philosophy extends Book {
    final static int DeweyDecimal = 601;
    }


    class JavaProgramming extends Book {
    final static int DeweyDecimal = 005;
    }


    class WebstersDictionary extends Book {
    final static int DeweyDecimal = 903;
    }
     
    Eric, Aug 25, 2005
    #12
  13. Eric

    Roedy Green Guest

    I am seeing each of your messages three times. Perhaps you are
    posting multiple times thinking they did not take. Sometimes it takes
    15 minutes or so for your news server to post newly received messages.
     
    Roedy Green, Aug 31, 2005
    #13
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.