wood burning stoves 2.0*
The moose likes Programming Diversions and the fly likes An atypical type puzzle (Java) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Other » Programming Diversions
Bookmark "An atypical type puzzle (Java)" Watch "An atypical type puzzle (Java)" New topic
Author

An atypical type puzzle (Java)

Istvan Kovacs
Ranch Hand

Joined: May 06, 2010
Posts: 100
We are all taught Java has single inheritance (each class may extend 0 or 1 class). We're also taught about the keyword final meaning no class may extend this one. Finally, we all know that abstract classes cannot be instantiated.

I'm now asking you to call TypePuzzle.puzzle with objects that get it to print "Good solution". The method classPuzzle does a number of checks:
  • child directly extends Object
  • child has (at least) two more supertypes
  • those supertypes are unrelated abstract final classes, whose instances are parent1 and parent2, respectively


  • Have fun! :-)

    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    Don't think that because no one has replied, no one is interested. This is a good one! I'm waiting for my old buddy Mike to stop by and tell us the answer though...


    [Jess in Action][AskingGoodQuestions]
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 38020
        
      22
    Unrelated abstract final classes? Can you have an abstract final class at all?
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    Campbell Ritchie wrote:Unrelated abstract final classes? Can you have an abstract final class at all?


    The compiler won't let you create one, but that doesn't mean the JVM can't make one for you.
    Istvan Kovacs
    Ranch Hand

    Joined: May 06, 2010
    Posts: 100
    Campbell Ritchie wrote: abstract final classes? Can you have an abstract final class at all?


    That's not the only weirdness here :-)
    Those classes are final, yet they'll have a subclass. They're also abstract, yet you'll need to pass an instance of each. You can even instantiate such a class without using the keyword new, but if you wish, you can use it.

    Ernest is on the right track.
    Istvan Kovacs
    Ranch Hand

    Joined: May 06, 2010
    Posts: 100
    Check Javadoc of Class.isAssignableFrom. It references the JLS. Widening reference conversions (the key to this puzzle) are in fact in section 5.1.5, not 5.1.4, here:
    http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.5.
    Just read that and follow links to the referenced sections.

    If there's no solution within a few days, I'll post an even more specific pointer to the relevant section of the JLS. After that, the solution becomes trivial.

    Mike Simmons
    Ranch Hand

    Joined: Mar 05, 2008
    Posts: 2994
        
        9

    Nice one, Istvan!
    Mike Simmons
    Ranch Hand

    Joined: Mar 05, 2008
    Posts: 2994
        
        9
    (And hi, EFH!)
    Istvan Kovacs
    Ranch Hand

    Joined: May 06, 2010
    Posts: 100
    Mike Simmons wrote:
    Nice one, Istvan!


    Glad you liked it :-)

    The idea came while I was writing an in-house training material on generics, and I wanted to show participants the differences between class hierarchies of arrays and typed ArrayList.
    Anil Bharadia
    Greenhorn

    Joined: Mar 12, 2009
    Posts: 15

    Ernest Friedman-Hill wrote:
    Campbell Ritchie wrote:Unrelated abstract final classes? Can you have an abstract final class at all?


    The compiler won't let you create one, but that doesn't mean the JVM can't make one for you.


    but how can i tell JVM that i want one ?


    Preparing SCJP 1.6
    Istvan Kovacs
    Ranch Hand

    Joined: May 06, 2010
    Posts: 100
    Anil Bharadia wrote:but how can i tell JVM that i want one ?


    You cannot ask the JVM to create one, they will be created automatically. Read on to find out why:

    The abstract, final classes in question are arrays.
    When you create a type (e.g. MyClass), the JVM creates the corresponding array class automatically.
    So, for each type (class or interface, what's more, even primitive types, like int), you have an array class that corresponds to it:
    int.class -> int[].class
    String.class -> String[].class
    MyClass.class -> MyClass[].class

    (If you are confused with the .class thing, it denotes the object representing the type. For example:


    The solution Mike has posted here used pre-defined types, but to understand what's going on, you can create ones of your own.


    By defining those interfaces and the class, you (get the JVM to) also implicitly define the corresponding array classes.
    A.class -> A[].class
    B.class -> B[].class
    C.class -> C[].class

    According to the Java Language Specification (JLS), if for two types it is true that

    then it also holds that


    Since class C implements both interfaces A and B, both will become supertypes (not superclasses!) of C, which means that a reference of interface A or B may be set to point to an instance of class C:



    This means that

    will hold, and thus

    will also hold.

    You cannot extend an array class, which made me suspect that they are final. Upon examining their modifiers (see lines 25-27 of the original puzzle code where superIsFinalAbstractClass is calculated), I found they were also abstract, which just made for a confusing-enough puzzle to post here.

    So

    is a valid solution.

    In Mike's answer, he used pre-defined types Integer, Serializable and Comparable, because the Integer class implements the interfaces Serializable and Comparable, just like class C implements interfaces A and B.
    Vlado Zajac
    Ranch Hand

    Joined: Aug 03, 2004
    Posts: 245
    Istvan Kovacs wrote:
    You cannot extend an array class, which made me suspect that they are final. Upon examining their modifiers (see lines 25-27 of the original puzzle code where superIsFinalAbstractClass is calculated), I found they were also abstract, which just made for a confusing-enough puzzle to post here.


    They may not be abstract in other JREs. According to getModifiers() API documentations, it is not defined if array classes have abstract modifier or not.
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    I think you just have to ignore the modifiers here. It really makes no sense for them to be abstract, as I can directly create instances with "new", and it makes no sense for them to be final because, as this puzzle shows, they enter into inheritance relationships. Maybe the "final" is helpful for a compiler, as the compiler won't let you the programmer extend such a class, and actually, the normal "new" bytecode isn't used for array objects, but rather there's a "newarray" bytecode, so perhaps the "abstract" makes sense as a signal to the compiler too.

    But in any case: thanks for posting this!
    Anil Bharadia
    Greenhorn

    Joined: Mar 12, 2009
    Posts: 15

    thanks Istvan,,

    i tried the following code



    now i unserstood the concept of array types

    Istvan Kovacs
    Ranch Hand

    Joined: May 06, 2010
    Posts: 100
    Ernest,

    I was also surprised to see that array classes are abstract. I was not too surprised about them being final, for the exact reason you mention, to prevent this:


    Arrays forming a type hierarchy is a necessary evil: before generics, we didn't have wildcards. If Java wanted to be able to handle arrays of related classes (like being able to provide a method that can sum arrays containing Number or any of its subtypes), there was no other way but to twist the type system to allow such hierarchies. The side effect is ArrayStoreException, and multiple superclasses for some classes in a language that advocates single inheritance between classes. :-(

    With generics and collections, we have a better way in the form of bounds and wildcards (T extends Number, ? extends Number). However, some generic code can look really frightening, e.g. Collections.min is defined as:


    Or (generified Observer/Observable from the book 'Java Generics and Collections'):


    But I'm getting off-topic :-)
    Avishkar Nikale
    Ranch Hand

    Joined: Aug 06, 2010
    Posts: 173
    This is a highly informative post.

    Thanks to all who gave their inputs.


    Regards,
    Avishkar Nikale
    Eugene Rabii
    Ranch Hand

    Joined: Apr 24, 2009
    Posts: 30
    This question made my day! Thank you so much!
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: An atypical type puzzle (Java)
     
    Similar Threads
    June Newsletter Puzzle
    SoDuko puzzle
    July Newsletter Puzzle (Maze Solver)
    two parents, one child, ora-02291
    Puzzle