How to access a member constant by FQN

Discussion in 'Java' started by Sideswipe, Sep 5, 2007.

  1. Sideswipe

    Sideswipe Guest

    I am curious how, if it's possible, I can access a constant declared
    in a class using only a fully qualified name

    example:

    package com.whatever.mycompany;

    public class MyConstants {

    public static final Integer MY_CONST = new Integer(10);
    }


    Object someConst = ...?

    With this last line I would like to fully qualify the constant as
    "com.whatever.mycompany.MyConstants.MY_CONST"

    It isn't a class I am after but an instance of a class. How do you ask
    the JVM for an existing instance in memory???

    Thanks
     
    Sideswipe, Sep 5, 2007
    #1
    1. Advertising

  2. Sideswipe

    Eric Sosman Guest

    Sideswipe wrote On 09/05/07 13:28,:
    > I am curious how, if it's possible, I can access a constant declared
    > in a class using only a fully qualified name
    >
    > example:
    >
    > package com.whatever.mycompany;
    >
    > public class MyConstants {
    >
    > public static final Integer MY_CONST = new Integer(10);
    > }
    >
    >
    > Object someConst = ...?
    >
    > With this last line I would like to fully qualify the constant as
    > "com.whatever.mycompany.MyConstants.MY_CONST"


    Object someConst =
    com.whatever.mycompany.MyConstants.MY_CONST;

    .... which seems so obvious that I suspect I've missed the
    point of your question.

    > It isn't a class I am after but an instance of a class. How do you ask
    > the JVM for an existing instance in memory???


    Now I'm *sure* I've missed something ... MY_CONST is
    a reference variable, a static member of MyConstants. It
    is initialized (when MyConstants is loaded) to refer to an
    Integer object. The Integer exists in memory. When you
    initialize someConst, another reference variable, it refers
    to that same, already-existing Integer instance. What do
    you find unsatisfactory about this state of affairs? (And
    how does name qualification or lack thereof enter into the
    picture?)

    --
     
    Eric Sosman, Sep 5, 2007
    #2
    1. Advertising

  3. Sideswipe

    Sideswipe Guest

    Hmm, ok, let me try this:

    Class.forName("com.whatever.mycompany.MyConstants");
    // MyConstants is now loaded and the static members initialized

    MY_CONST is now an Integer instance floating around in the JVM. So, I
    don't NEED a new instance of it, but I want to access it by a fully
    qualified name.

    When I do: Class.newInstance() <-- object is returned but if I am
    given the string: "com.whatever.mycompany.MyConstants.MY_CONST" I am
    not being given a FQN to a class, I am being given a FQN to a static
    final member of a Class.

    Another way to say it, how do I make an assignment to this instance
    based on the FQN as a String. This is all runtime/reflection -- not
    compile time so I have no way to know what will be referenced. If I
    knew the Outter class I could use reflection to get the fields and
    discover it by name, but I can't know that the String given to me
    represents a class and not one of it's members.

    Object someConst = ?
     
    Sideswipe, Sep 5, 2007
    #3
  4. Sideswipe wrote:
    > Hmm, ok, let me try this:
    >
    > Class.forName("com.whatever.mycompany.MyConstants");
    > // MyConstants is now loaded and the static members initialized
    >
    > MY_CONST is now an Integer instance floating around in the JVM. So, I
    > don't NEED a new instance of it, but I want to access it by a fully
    > qualified name.
    >
    > When I do: Class.newInstance() <-- object is returned but if I am
    > given the string: "com.whatever.mycompany.MyConstants.MY_CONST" I am
    > not being given a FQN to a class, I am being given a FQN to a static
    > final member of a Class.
    >
    > Another way to say it, how do I make an assignment to this instance
    > based on the FQN as a String.


    I don't think you fully appreciate the definition of static final...

    A static member is a member that exists for all instances of the class
    and only one ever exists. [*] A final variable is a variable that cannot
    be reassigned after it has been assigned once. Therefore, a static final
    variable is an non-reassignable variable that only ever exists once. It
    is for that reason that static final primitives, String's, and Class's
    (?) are inlined into the code. Furthermore, the Integer class is
    immutable, so none of its fields can change, so a static final Integer
    is truly unchangeable.


    > This is all runtime/reflection -- not compile time so I have no way to
    > know what will be referenced. If I knew the Outter class I could use
    > reflection to get the fields and discover it by name, but I can't know
    > that the String given to me represents a class and not one of it's
    > members.
    >
    > Object someConst = ?
    >


    1. Why do you need to use reflection?
    2. From where is the String given to you?
    3. Why can the String given to you represent a field?
    4. Why do you need to reassign a static final variable?

    If you still desperately want to do this, note that of any identifier,
    the simple name of the class will either appear as the rightmost, second
    from the right, are not at all (see the JLS). It should become clear how
    to proceed...

    [*] This definition will fail to hold under two conditions: the class
    information is collected by the GC, or the class is redefined using
    multiple class loaders. The former is generally not of too much concern,
    and the latter is only important when one is deeply involved with guts
    of the system, which I assume you are not.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Sep 5, 2007
    #4
  5. Sideswipe

    Lew Guest

    Joshua Cranmer wrote:
    > Sideswipe wrote:
    >> Hmm, ok, let me try this:
    >>
    >> Class.forName("com.whatever.mycompany.MyConstants");
    >> // MyConstants is now loaded and the static members initialized
    >>
    >> MY_CONST is now an Integer instance floating around in the JVM. So, I
    >> don't NEED a new instance of it, but I want to access it by a fully
    >> qualified name.


    The answer is
    com.whatever.mycompany.MyConstants.MY_CONST

    There is no "new instance of it".

    --
    Lew
     
    Lew, Sep 5, 2007
    #5
  6. Sideswipe wrote:
    > Hmm, ok, let me try this:
    >
    > Class.forName("com.whatever.mycompany.MyConstants");
    > // MyConstants is now loaded and the static members initialized
    >
    > MY_CONST is now an Integer instance floating around in the JVM. So, I
    > don't NEED a new instance of it, but I want to access it by a fully
    > qualified name.
    >
    > When I do: Class.newInstance() <-- object is returned but if I am
    > given the string: "com.whatever.mycompany.MyConstants.MY_CONST" I am
    > not being given a FQN to a class, I am being given a FQN to a static
    > final member of a Class.
    >
    > Another way to say it, how do I make an assignment to this instance
    > based on the FQN as a String. This is all runtime/reflection -- not
    > compile time so I have no way to know what will be referenced. If I
    > knew the Outter class I could use reflection to get the fields and
    > discover it by name, but I can't know that the String given to me
    > represents a class and not one of it's members.


    If I understand the problem, you have a String
    "com.whatever.mycompany.MyConstants.MY_CONST" and want to access the
    corresponding field.

    You first need to split it into the fully qualified class name and the
    field name. Use Class.forName to get a reference to the Class object.
    Use the Class's getField method to get a reference to the Field object
    for "MY_CONST". Take a look at the API documentation for Field to see
    how to do specific operations on the Field, such as getting a reference
    to the Integer.

    Almost, but not quite, always this sort of reflection tangle is a
    mistake, and there is a simpler, cleaner solution. It may be worth
    describing the problem you are trying to solve with all this.

    Patricia
     
    Patricia Shanahan, Sep 5, 2007
    #6
  7. Sideswipe

    Sideswipe Guest

    >
    > > Another way to say it, how do I make an assignment to this instance
    > > based on the FQN as a String.


    > I don't think you fully appreciate the definition of static final...


    I do fully appreciate what those qualifiers mean. I now can see how
    you got confused. Ok, let's take the case
    where I know this FQN at compile time. I could then do this:

    Object myObj = com.whatever.mycompany.MyConstants.MY_CONST;

    This is perfectly valid and trivial

    Now say I only have the above as a string representing the fully
    qualified name?


    I could do:
    Object myObj = null;
    Class c = Class.forName("com.whatever.mycompany.MyConstants");

    Field f = c.getField("MY_CONST");
    myObject = f.get(null);

    But that would be only possible if I knew that Containing class and
    the member I needed.

    >
    > 1. Why do you need to use reflection?

    Do you know of a way to access member fields at runtime without
    knowing their names?

    > 2. From where is the String given to you?

    A database? XML? Commandline? Does it matter?

    > 3. Why can the String given to you represent a field?

    I assume you mean "can't" -- and indeed it does or may

    > 4. Why do you need to reassign a static final variable?

    I don't, miscommunication issue. See above

    > If you still desperately want to do this, note that of any identifier,
    > the simple name of the class will either appear as the rightmost, second
    > from the right, are not at all (see the JLS). It should become clear how
    > to proceed...
    >


    If I assume that the string passed to me is a member field, I can do
    that above reflection. But, such a String could represent a fully
    qualified class name. At which point moving back one '.' would put me
    at the package level. Can I determine if a FQN is a Class or a Field
    in a Class? I know that, when referring to inner classes they are
    "com.blah.MyClass$Inner" -- but this isn't an inner class.



    I suppose I need a concrete example to really show people that despite
    honest bonifide credentials on this subject I am not a rookie. So,
    Here goes

    public class MyConstants {

    public static final SomeInterface CONST1 = new SomeSubtype() {
    public void interfaceMethod() {}
    };

    public static final SomeInterface CONST2 = new SomeSubtype() {
    public void interfaceMethod() {}
    };

    public static final SomeInterface CONST3 = new SomeSubtype() {
    public void interfaceMethod() {}
    };

    }

    SomeInterface x = MyConstants.CONST1; // trivial.

    SomeInterface X = ..? // do the above given only this string:
    "MyConsts.CONST1"; // This string is passed at runtime
     
    Sideswipe, Sep 6, 2007
    #7
  8. Sideswipe

    Roedy Green Guest

    On Wed, 05 Sep 2007 17:28:03 -0000, Sideswipe
    <> wrote, quoted or indirectly quoted
    someone who said :

    >With this last line I would like to fully qualify the constant as
    >"com.whatever.mycompany.MyConstants.MY_CONST"
    >
    >It isn't a class I am after but an instance of a class. How do you ask
    >the JVM for an existing instance in memory???


    I think you are using the word "instance" incorrectly. If you truly
    meant instance you would have to say something like

    TheClass anInstance = new TheClass();

    Object x = anInstance.MY_CONST;

    If you what you mean is a fully qualify class you must either import
    that class, possibly import static. Or fully qualify the reference
    e.g.

    Integer x = com.whatever.mycompany.MyConstants.MY_CONST;

    see http://mindprod.com/jgloss/import.html
    http://mindprod.com/jgloss/package.html
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Sep 6, 2007
    #8
  9. Sideswipe

    Mark Space Guest

    Sideswipe wrote:

    > SomeInterface X = ..? // do the above given only this string:
    > "MyConsts.CONST1"; // This string is passed at runtime
    >


    My gut feeling is... if you need "MyConstants" and you get passed
    "MyConstants.CONST1" you've been supplied an incorrect parameter.

    You write a function. You need to be passed a 3. Someone passes you a
    4. This is wrong. You could subtract one from four to get three, but
    then if you *ARE* passed a 3 you'd end up with a 2, and this is wrong.
    How do you solve this dilemma?

    Throw an error if you get passed something besides a 3. Anything else
    is incorrect, it's that simple.

    I guess you could try to instantiate the string you get. If it doesn't
    go, try stripping off one "." and try again. That's all I can think of.
    You could also, I suppose, search through the class path and try to
    ID which parts of the string are package and which parts are class. You
    are just duplicating the effort that the classloader will make when you
    try to instantiate a class tho, I think.

    If you have more control over your input, pass two parameters. The
    first is the class, the second is a field. The second parameter can be
    null or "". That's the only other idea I got.
     
    Mark Space, Sep 6, 2007
    #9
  10. Sideswipe

    Sideswipe Guest

    Patricia,

    >From my prior post I did offer that as a solution I just wasn't sure

    there wasn't something easier. But you have correctly identified what
    I was trying to ask. I didn't realize it would be so hard. Often times
    I ask questions in this group not because I want to implement said
    question, but because I am trying to see if it's even possible. Part
    of the way I learn is to always push the boundries of what I know is
    possible.

    Thanks for confirming my suspicions.

    Christian Bongiorno
     
    Sideswipe, Sep 6, 2007
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fraser Ross
    Replies:
    4
    Views:
    1,067
    Fraser Ross
    Aug 14, 2004
  2. Christopher M. Lusardi
    Replies:
    1
    Views:
    4,111
  3. Martin Magnusson
    Replies:
    2
    Views:
    518
    John Harrison
    Oct 8, 2004
  4. Tor Erik Soenvisen
    Replies:
    14
    Views:
    576
    Tim Roberts
    Nov 23, 2006
  5. Replies:
    4
    Views:
    348
    Keith Thompson
    Dec 14, 2006
Loading...

Share This Page