Class.cast(Object) - what benefit?

Discussion in 'Java' started by Ian Pilcher, Aug 20, 2005.

  1. Ian Pilcher

    Ian Pilcher Guest

    Ian Pilcher, Aug 20, 2005
    #1
    1. Advertising

  2. Raymond DeCampo, Aug 20, 2005
    #2
    1. Advertising

  3. Patricia Shanahan wrote:
    > Roedy Green wrote:
    >
    >> On Sat, 20 Aug 2005 11:54:42 -0500, Ian Pilcher
    >> <> wrote or quoted :
    >>
    >>
    >>> But I can't figure out what benefit it provides. Can anyone come up
    >>> with a usage scenario?

    >>
    >>
    >>
    >> Perhaps it is just shorthand for checking if the object is of the
    >> right class and if not throwing an exception.
    >>

    >
    > I don't think it's that, because, according to the API documentation, it
    > throws ClassCastException "if the object is not null and is not
    > assignable to the type T."
    >
    > It seems more likely to be something to do with generics, but I haven't
    > worked out what.
    >
    > Patricia


    The scenario I am imagining is that you have a generic class
    parametrized by class T. Somewhere in this class you have an Object
    that you want to cast to type T. Presumably the syntax

    T t = (T)obj;

    is illegal. So one would use the Class.cast() method. Although I'm not
    sure how you get an instance of Class<T> in this case.

    DISCLAIMER: I haven't worked with generics, so the above may be totally
    wrong, misguided and generally rot. Also, I may have used the incorrect
    vocabulary.

    Ray

    --
    XML is the programmer's duct tape.
    Raymond DeCampo, Aug 21, 2005
    #3
  4. Raymond DeCampo wrote:
    >
    > The scenario I am imagining is that you have a generic class
    > parametrized by class T. Somewhere in this class you have an Object
    > that you want to cast to type T. Presumably the syntax
    >
    > T t = (T)obj;
    >
    > is illegal. So one would use the Class.cast() method. Although I'm not
    > sure how you get an instance of Class<T> in this case.


    When you construct a class with generic parameter T, you can pass in a
    Class<T>. You can then do the cast with both static and dynamic
    checking, which (T) does not give you. It also doesn't produce unchecked
    warnings, because it is checked (at that point).

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Aug 22, 2005
    #4
  5. Thomas Hawtin wrote:
    > Raymond DeCampo wrote:
    >
    >>
    >> The scenario I am imagining is that you have a generic class
    >> parametrized by class T. Somewhere in this class you have an Object
    >> that you want to cast to type T. Presumably the syntax
    >>
    >> T t = (T)obj;
    >>
    >> is illegal. So one would use the Class.cast() method. Although I'm
    >> not sure how you get an instance of Class<T> in this case.

    >
    >
    > When you construct a class with generic parameter T, you can pass in a
    > Class<T>.


    That seems hokey. I expected a more natural mechanism. (Please do not
    misinterpret, you are the messenger, I am criticizing the composer of
    the message, so to speak.)

    This whole Class<T> thing doesn't sit well with me somehow. It helps
    for some reason to remember that generics are implemented via erasure.

    > You can then do the cast with both static and dynamic
    > checking, which (T) does not give you. It also doesn't produce unchecked
    > warnings, because it is checked (at that point).
    >
    > Tom Hawtin


    Ray

    --
    XML is the programmer's duct tape.
    Raymond DeCampo, Aug 22, 2005
    #5
  6. Ian Pilcher wrote:
    > I just noticed it at:
    >
    > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#cast(java.lang.Object)
    >
    >
    > But I can't figure out what benefit it provides. Can anyone come up
    > with a usage scenario?


    See

    http://www.langer.camelot.de/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ602

    in Angelika Langer's generics FAQ.

    /Thomas
    --
    The comp.lang.java.gui FAQ:
    ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
    http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
    Thomas Weidenfeller, Aug 22, 2005
    #6
  7. Ian Pilcher

    Ian Pilcher Guest

    Thomas Weidenfeller wrote:
    >
    > See
    >
    > http://www.langer.camelot.de/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ602
    >


    I see it used, but there's no explanation of why it's there. The best
    I can figure out, it's just a shortcut for:

    if (!cls.isInstance(o))
    throw new ClassCastException(...)

    --
    ========================================================================
    Ian Pilcher
    ========================================================================
    Ian Pilcher, Aug 22, 2005
    #7
  8. Ian Pilcher

    Roedy Green Guest

    On Mon, 22 Aug 2005 01:09:15 +0100, Thomas Hawtin
    <> wrote or quoted :

    >When you construct a class with generic parameter T, you can pass in a
    >Class<T>. You can then do the cast with both static and dynamic
    >checking, which (T) does not give you. It also doesn't produce unchecked
    >warnings, because it is checked (at that point).


    I'll do some decompilation to verify this if someone has not already.


    Is there ANY run time code that protects a typed ArrayList from
    getting the wrong objects in it? I presume not. It is fully type
    erased.

    There must be a run-time cast somewhere when you take Objects out of
    the typed ArrayList. I presume the compiler inserts these after a get
    call. They are part of the calling code, not the ArrayList.

    These casts were necessary even if you had 100% confidence they would
    always succeed.
    Roedy Green, Aug 22, 2005
    #8
  9. Ian Pilcher wrote:
    > I see it used, but there's no explanation of why it's there. The best
    > I can figure out, it's just a shortcut for:
    >
    > if (!cls.isInstance(o))
    > throw new ClassCastException(...)


    No, you're missing the point, which is that the cast can be typechecked
    at compile time. More specifically, the cast of an object of generic
    type can be typechecked at compile time, making it possible to avoid an
    "unchecked cast" warning and *ensure* that no ClassCastException will be
    thrown.

    Example [Not tested]:

    class ListHolder <T> {

    private List<T> list;

    // ...

    public <S> S getElement(Class<S> clazz, int i) {

    // Compatibility of S and T checked at compile time,
    // on a per-invocation basis:

    return clazz.cast(list.get(i));
    }
    }


    Note that two distinct type parameters are involved in my example; I
    can't imagine Class.cast() being useful with fewer.

    --
    John Bollinger
    John C. Bollinger, Aug 23, 2005
    #9
  10. Hi,

    John C. Bollinger wrote:
    > public <S> S getElement(Class<S> clazz, int i) {

    ^^^ ^^^
    But that means that you have to pass the Type-Parameter (S) twice which
    is not a good idea!

    And "S.class" doesn't work.

    Ciao,
    Ingo
    Ingo R. Homann, Aug 23, 2005
    #10
  11. Ingo R. Homann wrote:
    > Hi,
    >
    > John C. Bollinger wrote:
    >
    >> public <S> S getElement(Class<S> clazz, int i) {

    >
    > ^^^ ^^^
    > But that means that you have to pass the Type-Parameter (S) twice which
    > is not a good idea!


    Oh no you don't!

    > And "S.class" doesn't work.


    That's why he passed a Class<S>.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Aug 23, 2005
    #11
  12. Hi,

    Thomas Hawtin wrote:
    >>> public <S> S getElement(Class<S> clazz, int i) {

    >> ^^^ ^^^
    >> But that means that you have to pass the Type-Parameter (S) twice
    >> which is not a good idea!

    >
    > Oh no you don't!


    Well, now, then how do you call it?

    Ciao,
    Ingo
    Ingo R. Homann, Aug 23, 2005
    #12
  13. Ingo R. Homann wrote:
    >
    > Thomas Hawtin wrote:
    >
    >>>> public <S> S getElement(Class<S> clazz, int i) {
    >>>
    >>> ^^^ ^^^
    >>> But that means that you have to pass the Type-Parameter (S) twice
    >>> which is not a good idea!

    >>
    >>
    >> Oh no you don't!

    >
    >
    > Well, now, then how do you call it?


    class MyCLass {
    String myFunc(ListHolder<CharSequence> listHolder) {
    return listHolder.getElement(String.class, 0);
    }
    }

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Aug 23, 2005
    #13
  14. Hi,

    Thomas Hawtin wrote:
    >>>>> public <S> S getElement(Class<S> clazz, int i) {
    >>>> ^^^ ^^^
    >>>> But that means that you have to pass the Type-Parameter (S) twice
    >>>> which is not a good idea!

    >>
    >> Well, now, then how do you call it?

    >
    > class MyCLass {
    > String myFunc(ListHolder<CharSequence> listHolder) {
    > return listHolder.getElement(String.class, 0);
    > }
    > }


    Eh, I think it must be

    listHolder.<String>getElement(String.class, 0);

    to get no warning.

    Ciao,
    Ingo
    Ingo R. Homann, Aug 23, 2005
    #14
  15. Ingo R. Homann wrote:
    >
    > Eh, I think it must be
    >
    > listHolder.<String>getElement(String.class, 0);
    >
    > to get no warning.


    Nope. The type is inferred. Same as with EnumSet.of.

    I have tried that exact code on 1.5.0-b64, 1.5.0_04-b05 and
    1.6.0-ea-b48. It compiles without a whisper.

    Tom Hawtin
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Aug 23, 2005
    #15
  16. Hi,

    Thomas Hawtin wrote:
    >> Eh, I think it must be
    >>
    >> listHolder.<String>getElement(String.class, 0);
    >>
    >> to get no warning.

    >
    > Nope. The type is inferred. Same as with EnumSet.of.
    >
    > I have tried that exact code on 1.5.0-b64, 1.5.0_04-b05 and
    > 1.6.0-ea-b48. It compiles without a whisper.


    I just tried it with Eclipse 3.1 final (which I admit is not such a good
    reference-implementation as your different JDKs) and...

    ....it compiles without a whisper.

    Very interesting, I never expected that!

    Thanks,
    Ingo
    Ingo R. Homann, Aug 23, 2005
    #16
  17. Ian Pilcher

    Ian Pilcher Guest

    John C. Bollinger wrote:
    > No, you're missing the point, which is that the cast can be typechecked
    > at compile time. More specifically, the cast of an object of generic
    > type can be typechecked at compile time, making it possible to avoid an
    > "unchecked cast" warning and *ensure* that no ClassCastException will be
    > thrown.


    I've tested and enhanced your example a little bit, and I may see the
    point, but I surely don't agree with it.

    package temp;

    import java.util.*;

    class ListHolder<T>
    {
    private List<T> list;

    public ListHolder(List<T> list)
    {
    this.list = list;
    }

    public <S> S getElementAs(Class<S> cls, int i)
    {
    return cls.cast(list.get(i)); // no warning
    // return (S)(list.get(i)); // warning
    }
    }

    class Cast
    {
    public static void main(String[] args)
    {
    List<Integer> list = new LinkedList<Integer>();
    list.add(new Integer(0));
    ListHolder<Integer> holder = new ListHolder<Integer>(list);

    // This is compatible
    Object o = holder.getElementAs(Object.class, 0);

    // This is not
    List l = holder.getElementAs(List.class, 0);
    }
    }

    You're right that the Class.cast form does not throw an "unchecked cast"
    warning, and the normal cast does. That seems to be the only
    difference, however, and you've provided a perfect example of why this
    warning is stupid in the first place.

    --
    ========================================================================
    Ian Pilcher
    ========================================================================
    Ian Pilcher, Aug 23, 2005
    #17
    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. keithb

    Southwest Driver Benefit

    keithb, Mar 30, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    319
    keithb
    Mar 30, 2006
  2. tom
    Replies:
    0
    Views:
    386
  3. Half Dolla 2003

    Can CSS benefit non-liquid layouts?

    Half Dolla 2003, Jul 22, 2003, in forum: HTML
    Replies:
    10
    Views:
    773
    Adrienne
    Jul 26, 2003
  4. DaTurk
    Replies:
    6
    Views:
    353
    Ian Collins
    Jan 25, 2007
  5. maverik
    Replies:
    0
    Views:
    411
    maverik
    Nov 27, 2008
Loading...

Share This Page