Default primitive values from primitive Class<?> object.

Discussion in 'Java' started by Daniel Pitts, Oct 22, 2008.

  1. Daniel Pitts

    Daniel Pitts Guest

    I have some generic reflection based code which "clears" a JavaBean
    based on the PropertyDescriptors. Initially, I set everything to "null"
    which worked until I put a boolean (not Boolean) in one of my beans.

    I special cased boolean, and that is fine, but I know that sometime
    someone is going to ask for an "int" or a "long", etc...

    I have the Class<?> from the propertyDescriptor and was wondering if
    there was any easy way to map from that Class<?> to an appropriate
    "default" wrapper? If there isn't a built-in way, I can always use a
    Map<Class<?>, Object>, and just initialize it with new Integer(0), new
    Double(0), etc...
    Not quite the best approach in my opinion.



    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Oct 22, 2008
    #1
    1. Advertising

  2. Daniel Pitts

    zerg Guest

    Daniel Pitts wrote:
    > I have the Class<?> from the propertyDescriptor and was wondering if
    > there was any easy way to map from that Class<?> to an appropriate
    > "default" wrapper? If there isn't a built-in way, I can always use a
    > Map<Class<?>, Object>, and just initialize it with new Integer(0), new
    > Double(0), etc...
    > Not quite the best approach in my opinion.


    No; brute force is probably the best approach, given how few primitive
    types there are. Just special-case each one the way you already have
    boolean.
    zerg, Oct 22, 2008
    #2
    1. Advertising

  3. Daniel Pitts

    Daniel Pitts Guest

    zerg wrote:
    > Daniel Pitts wrote:
    >> I have the Class<?> from the propertyDescriptor and was wondering if
    >> there was any easy way to map from that Class<?> to an appropriate
    >> "default" wrapper? If there isn't a built-in way, I can always use a
    >> Map<Class<?>, Object>, and just initialize it with new Integer(0), new
    >> Double(0), etc...
    >> Not quite the best approach in my opinion.

    >
    > No; brute force is probably the best approach, given how few primitive
    > types there are. Just special-case each one the way you already have
    > boolean.

    That's what I thought :-(
    Here's what I did:
    private static final Map<Class<?>, Object> defaultValues;
    static {
    final Map<Class<?>, Object> values = new HashMap<Class<?>, Object>();
    defaultValues = Collections.unmodifiableMap(values);
    values.put(Boolean.TYPE, false);
    values.put(Integer.TYPE, 0);
    values.put(Short.TYPE, (short) 0);
    values.put(Long.TYPE, 0L);
    values.put(Float.TYPE, 0f);
    values.put(Double.TYPE, 0d);
    values.put(Character.TYPE, (char)0);
    values.put(Byte.TYPE, (byte)0);
    }

    // elsewhere
    setProperty(property, bean, defaultValues.get(property.getPropertyType()));


    where setProperty actually invokes the property's write method on the
    given bean with the given value.

    This works for all cases, since map.get(*) will return null if there
    isn't a specific value. This lets me add "custom" default values later
    on if I need to.


    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Oct 22, 2008
    #3
  4. Daniel Pitts

    Mark Space Guest

    Daniel Pitts wrote:

    > This works for all cases, since map.get(*) will return null if there
    > isn't a specific value.


    Clever. I missed that reading the code. Might want to mention it in a
    comment somewhere....
    Mark Space, Oct 23, 2008
    #4
  5. On Oct 22, 3:51 pm, Daniel Pitts
    <> wrote:
    > I have some generic reflection based code which "clears" a JavaBean
    > based on the PropertyDescriptors.  Initially, I set everything to "null"
    > which worked until I put a boolean (not Boolean) in one of my beans.
    >
    > I special cased boolean, and that is fine, but I know that sometime
    > someone is going to ask for an "int" or a "long", etc...
    >
    > I have the Class<?> from the propertyDescriptor and was wondering if
    > there was any easy way to map from that Class<?> to an appropriate
    > "default" wrapper?  If there isn't a built-in way, I can always use a
    > Map<Class<?>, Object>, and just initialize it with new Integer(0), new
    > Double(0), etc...
    > Not quite the best approach in my opinion.


    On the contrary. This actually lets you plug in "default" values for
    any type you want. However, rather than hardcoding the map, I'd
    provide a convenience tool that constructs a map containing only
    defaults for primitive-wrapper and primitive types and accept a
    default map as a parameter to the 'resetter' method (or class); if the
    consumer wants to use the defaults, they can, or they can provide any
    map they want. The result is flexible in potentially-useful ways.

    -o
    Owen Jacobson, Oct 23, 2008
    #5
  6. Daniel Pitts

    Daniel Pitts Guest

    Lew wrote:
    > Daniel Pitts wrote:
    >>> This works for all cases, since map.get(*) will return null if there
    >>> isn't a specific value.

    >
    > Mark Space wrote:
    >> Clever. I missed that reading the code. Might want to mention it in
    >> a comment somewhere....

    >
    > <http://java.sun.com/javase/6/docs/api/java/util/Map.html#get(java.lang.Object)>
    >
    > Map#get()
    >> Returns the value to which the specified key is mapped, or null if
    >> this map contains no mapping for the key.

    >
    > I started thinking twistedly - how could one retrieve just the normal
    > default values, letting Java decide what they are, without a Map, even
    > for automatic variables?
    >
    > <sscce>
    > package testit;
    >
    > /** Show strange use of anonymous class to get default value. */
    > public class OverGet
    > {
    > /** Show strange use of anonymous class to get default value. */
    > public void foo()
    > {
    > int huhQ =
    > new Object()
    > {
    > int huh;
    > public int getHuh()
    > {
    > return huh;
    > }
    > }.getHuh();
    > System.out.println( huhQ );
    > }
    >
    > /** Entry point.
    > * @param args <code>String []</code> command line arguments.
    > */
    > public static void main( String [] args )
    > {
    > new OverGet().foo();
    > }
    >
    > }
    > </sscce>
    >

    Well, I'm in a codebase that is doing heavy reflection, so I can do this
    (untested, and probably won't end up in production):
    private static final defs = new Object() {
    byte by; boolean bo; char c; int i; float f; double d; short s;
    }
    for (Field field: defs.getClass().getDeclaredFields()) {
    defaultValues.put(field.getType(), field.get(defs));
    }

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Oct 23, 2008
    #6
  7. Daniel Pitts

    Daniel Pitts Guest

    Owen Jacobson wrote:
    > On Oct 22, 3:51 pm, Daniel Pitts
    > <> wrote:
    >> I have some generic reflection based code which "clears" a JavaBean
    >> based on the PropertyDescriptors. Initially, I set everything to "null"
    >> which worked until I put a boolean (not Boolean) in one of my beans.
    >>
    >> I special cased boolean, and that is fine, but I know that sometime
    >> someone is going to ask for an "int" or a "long", etc...
    >>
    >> I have the Class<?> from the propertyDescriptor and was wondering if
    >> there was any easy way to map from that Class<?> to an appropriate
    >> "default" wrapper? If there isn't a built-in way, I can always use a
    >> Map<Class<?>, Object>, and just initialize it with new Integer(0), new
    >> Double(0), etc...
    >> Not quite the best approach in my opinion.

    >
    > On the contrary. This actually lets you plug in "default" values for
    > any type you want. However, rather than hardcoding the map, I'd
    > provide a convenience tool that constructs a map containing only
    > defaults for primitive-wrapper and primitive types and accept a
    > default map as a parameter to the 'resetter' method (or class); if the
    > consumer wants to use the defaults, they can, or they can provide any
    > map they want. The result is flexible in potentially-useful ways.
    >
    > -o

    That approach may be useful in the future, but this is a specific enough
    (and large enough) codebase that I'm trying to avoid YAGNI features.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Oct 23, 2008
    #7
  8. Daniel Pitts

    Lew Guest

    Lew wrote:
    >> I started thinking twistedly - how could one retrieve just the normal
    >> default values, letting Java decide what they are, without a Map, even
    >> for automatic variables?
    >>
    >> <sscce>
    >> package testit;
    >>
    >> /** Show strange use of anonymous class to get default value.   */
    >> public class OverGet
    >> {
    >>  /** Show strange use of anonymous class to get default value.  */
    >>  public void foo()
    >>  {
    >>    int huhQ =
    >>      new Object()
    >>      {
    >>        int huh;
    >>        public int getHuh()
    >>        {
    >>          return huh;
    >>        }
    >>      }.getHuh();
    >>    System.out.println( huhQ );
    >>  }
    >>
    >>  /** Entry point.
    >>   * @param args <code>String []</code> command line arguments.
    >>   */
    >>  public static void main( String [] args )
    >>  {
    >>   new OverGet().foo();
    >>  }
    >>
    >> }
    >> </sscce>


    Daniel Pitts wrote:
    > Well, I'm in a codebase that is doing heavy reflection, so I can do this
    > (untested, and probably won't end up in production):
    > private static final defs = new Object() {
    >     byte by; boolean bo; char c; int i; float f; double d; short s;}
    >
    > for (Field field: defs.getClass().getDeclaredFields()) {
    >     defaultValues.put(field.getType(), field.get(defs));
    >
    > }


    Huh.

    Shows that even wacky ideas can have their place. I didn't even see
    it as that useful until I saw your example.

    In your code, you could make defs a temporary variable inside an
    initializer block.

    I came up with a poetic variant of the idiom specific to 'double':

    double duh = new Object(){double duh;}.duh;

    --
    Lew
    Lew, Oct 23, 2008
    #8
    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. Skippy
    Replies:
    1
    Views:
    366
    Roedy Green
    Sep 6, 2003
  2. Replies:
    7
    Views:
    591
    Victor Bazarov
    May 9, 2005
  3. =?Utf-8?B?YW1hem9u?=

    passing non-primitive values to array class

    =?Utf-8?B?YW1hem9u?=, Nov 5, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    336
    =?Utf-8?B?YW1hem9u?=
    Nov 5, 2006
  4. Dzikus
    Replies:
    0
    Views:
    319
    Dzikus
    Jul 25, 2007
  5. Asen Bozhilov

    in, instanceof and primitive values?

    Asen Bozhilov, Nov 23, 2009, in forum: Javascript
    Replies:
    3
    Views:
    93
    Asen Bozhilov
    Nov 24, 2009
Loading...

Share This Page