Thread: Java: Why isn't this allowed?

  1. #1
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072

    Java: Why isn't this allowed?

    Consider this example of valid code:
    Code:
    class Test<E> {
        E[] array;
        
        Test() {
            array = (E[]) new Object[100];
        }
    }
    What is the reason that the following isn't allowed?
    Code:
    array = new E[100];
    It seems stupid that this isn't allowed because the original code is unelegant and will generate a warning. It is also a needed construction in a lot of containers.
    I don't see any reason why the 'new E'-notation shouldn't be allowed. It doesn't create any E objects, so E doesn't have to be a known type.

    I've asked my lecturer, but she doesn't have an answer.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  2. #2
    Nonconformist Narf's Avatar
    Join Date
    Aug 2005
    Posts
    174
    Read section 7.3 in the following tutorial for why this isn't allowed:
    http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
    Just because I don't care doesn't mean I don't understand.

  3. #3
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    This is what the tutorial says:
    Quote Originally Posted by tutorial
    Similarly, attempting to create an array object whose element type is a type variable causes a compile-time error:
    Code:
    <T> T[] makeArray(T t) { return new T[100]; // error
    }
    Since type variables don’t exist at run time, there is no way to determine what the actual array type would be.
    I don't agree here. Sure, the type T isn't known, but no T object is created, only references (100 of them) to T objects are created (and set to null).

    The only thing I ask is that
    Code:
    E[] array = new E[100];
    should be interpreted as
    Code:
    E[] array = (E[]) new Object[100];
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  4. #4
    Nonconformist Narf's Avatar
    Join Date
    Aug 2005
    Posts
    174
    I don't agree here.
    Feel free to email Sun and ask them to change the language to suit your preferences.
    Just because I don't care doesn't mean I don't understand.

  5. #5
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by Narf
    Feel free to email Sun and ask them to change the language to suit your preferences.
    Feel free to not post in this thread unless you have something useful to say.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  6. #6
    Nonconformist Narf's Avatar
    Join Date
    Aug 2005
    Posts
    174
    Quote Originally Posted by Sang-drax
    Feel free to not post in this thread unless you have something useful to say.
    My suggestion was very serious. I'm sorry that you don't approve of reality, but if you don't like it, you can suggest changes to Sun. But thanks for your rude and insulting response anyway. I always appreciate being wrongly flamed by ..............s.
    Just because I don't care doesn't mean I don't understand.

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    This went downhill fast.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  8. #8
    Supermassive black hole cboard_member's Avatar
    Join Date
    Jul 2005
    Posts
    1,709
    Quote Originally Posted by Zach L.
    This went downhill fast.
    Yes much faster than one of my threads, I thought I'd be holding the record for longer
    Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.

    - Mike McShaffry

  9. #9
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    That's allowed in C++ because the compiler compiles the templated code for each template instance, and links at the end.
    Instead, the Java VM instantiates the templated code at runtime (which is slower) causing that issue.

  10. #10
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    But everything works with the cast, which means that the question isn't whether it is possible or not, but rather why they choose not to allow it.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  11. #11
    Registered User Frobozz's Avatar
    Join Date
    Dec 2002
    Posts
    546
    They've given their reason.

    Quote Originally Posted by Sun documentation
    Since type variables don’t exist at run time, there is no way to determine what the actual array type would be.
    If you don't think that is a good enough answer, try asking on the Java forums

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Sang-drax
    The only thing I ask is that
    Code:
    E[] array = new E[100];
    should be interpreted as
    Code:
    E[] array = (E[]) new Object[100];
    But the (E[]) cast is a no-op. E is (unless it's defined as 'extends XXX') completely replaced by Object in the resulting bytecode. All you're doing is casting an object array to an object array. The only effect of generics are the casts the compiler writes into the code automatically.

    Allowing "new E[10]" would lead to the misconception that the runtime type of the array would be E[]. It isn't. It's Object[], which cannot be cast to any more specialized array type. For example, this code throws a class cast exception:
    String[] bla = (String[]) new Object[10];

    On the other hand, this code is valid, the runtime type being String[]:
    String[] bla = new String[10];

    Allowing this:
    E[] bla = new E[10];
    would lead people to believe that the runtime type is E[]. This can be dangerous. And that's why it's not allowed.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by CornedBee
    The only effect of generics are the casts the compiler writes into the code automatically.
    Thanks!

    If I were able to write
    Code:
    E[] array = new E[10]
    it'd be interpreted as
    Code:
    Object[] array = new Object[10];
    But would this be unsafe? I still cannot do:
    Code:
    Object someObject = ...
    array[2] = someObject;
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  14. #14
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Hmm, I guess that's why the equals method doesn't work in this case.
    Code:
    import java.io.*;
    
    class Number implements Comparable<Number> {
        int n;
        Number(int n) {
           this.n = n;
        }
        int get() {
            return n;
        }
        public boolean equals(Number number) {
           return n == number.get();
        }
        public int compareTo(Number number) {
    	Integer i = new Integer(n);
    	return i.compareTo(number.get());
        }
    }
    
    class  TestContainer<E extends Comparable<E> > {
        TestContainer() {
        }
        boolean isSame(E e1, E e2) {
            return e1.equals(e2);
        }
        int compare(E e1, E e2) {
    	return e1.compareTo(e2);
        }
    }
    
    public class Test {   
    
        public static void main(String[] arguments) {
    	Number n1 = new Number(3);
    	Number n2 = new Number(3);
    	Number n3 = new Number(4);
    	TestContainer<Number> testContainer = new TestContainer<Number>();
    	//Compare two equal elements
            System.out.println(testContainer.isSame(n1,n2));
    	System.out.println(testContainer.compare(n1,n2));
    	//Compare two different elements
    	System.out.println(testContainer.compare(n1,n3));
    	System.out.println(testContainer.compare(n3,n1));
        }
        
    }
    I still haven't Java generics 100% figured out.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The equals method is not generic. It always takes an Object parameter.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Java for real-time applications
    By zacs7 in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 08-26-2008, 06:34 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. C#, Java, C++
    By incognito in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 10-05-2004, 02:06 PM
  4. The Java language is being expanded
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 26
    Last Post: 06-11-2004, 09:07 PM
  5. Java woes
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 07-06-2003, 12:37 AM