Downcasting a subclass of a concrete generic

Hi--
Been puzzling over this one for quite awhile, and I still can't figure it out. I'm trying to downcast a generic type to a subclass of a concrete type. Now admittedly that's messy and I'd like to refactor, but I'm still puzzled. Take the following code:
public class Test1<T> {
    protected final T obj;
    public Test1(T obj) {
     this.obj = obj;
    public static void main(String[] args) {
     Test1<?> testObj = new Test2("hello");
     System.err.println("Calling a method: " + ((Test2) testObj)).aMethod());
public class Test2 extends Test1<String> {
    public Test2(String obj) {
     super(obj);
    public String aMethod() {
     return obj;
}This fails to compile, saying that Test1<capture of ?> isn't convertible to Test2.
Now suppose I change to the following:
public class Test1<T> {
    protected final T obj;
    public Test1(T obj) {
     this.obj = obj;
    public static void main(String[] args) {
     Test1<?> testObj = new Test2<String>("hello");
     System.err.println("Calling a method: " + ((Test2) testObj).anotherMethod());
public class Test2<T extends String> extends Test1<T> {
    public Test2(T obj) {
     super(obj);
    public String anotherMethod() {
     return obj;
}Here all I've done is add a parameter to the Test2 type that gives the same information available in item 1. In this case, however, it compiles and runs fine.
Even more oddly, the following also works and does not produce any warnings:
public class Test1<T> {
    protected final T obj;
    public Test1(T obj) {
     this.obj = obj;
    public static void main(String[] args) {
     Test1<?> testObj = new Test2("hello");
     System.err.println("Calling a method: " + ((Test2) ((Test1) testObj)).anotherMethod());
public class Test2 extends Test1<String> {
    public Test2(String obj) {
     super(obj);
    public String anotherMethod() {
     return obj;
}So essentially the system is ok as long as I cast the generic type to a raw type, and then downcast to the subclass of the concrete type... but I can't do the cast directly?
My feeling is that Java is being a little overly touchy about trying to prevent casting to a concrete type-- in the case where the type you're trying to cast to is itself not generic, shouldn't that be allowed? Or am I missing something subtle about how the generics work?

Correct me if I'm wrong, but I think this may be your problem:
public class Test2 extends Test1<String> {
}This means that Test2 is a subclass of Test1<String> -- not Test1<?>. Here's why.
If we "expand out," say, Test1<Integer> and Test1<String>, we get the following:
public class Test1String {
   protected final String obj;
   public Test1String(String obj) {
   this.obj = obj;
public class Test1Integer{
   protected final Integer obj;
   public Test1Integer(Integer obj) {
   this.obj = obj;
}Now, it's easy to see that inheriting from each of these classes yields completely different results. Once you've parameterized a class, it becomes a completely different beast. Sooo, saying that
Test1<?> testObj = new Test2("hello");could be the same thing as saying (since ? means any parameter), in our expanded form,
Test1Integer testObj = new Test2("hello"); //aka, a new Test1String
//or Test1Object, Test1MyComplicatedType, whateverwhich is clearly not allowed, since all the fields would be of a completely different type.
I hope this helps!

Similar Messages

  • Typed subclass of HashMap using generics

    I am a newbie to generics and was wondering if it's possible to create a subclass of HashMap that only accepts a String as a key and any Object as a value (or even better a generic object type as a value).
    I thought the code would have been something like this but the super call doesn't work.
    public class MyMap extends HashMap {
      public MyMap() {
        super<String, Object>();
    }Any help greatly appreciated.

    Try this:public class MyMap<V> extends HashMap<String, V> {
      public MyMap() {
        super();
    }

  • My source does not compile in 1.5 because of generics in libraries

    Hi,
    I have a problem with my source codes written for 1.3 and 1.4 java. I have been implementing Iterator, Collection, List and extending ArrayList in many ocassions. All works as expected in 1.4 but if I try to compile it with 1.5 it does not compile. I do receive many errors which generally speaking are showing that compiler does think that X subclass is not the same as a subclass of X<?> generic which simply makes all my code to not compile.
    Does anybody had similar problems with their code? Does anybody knows how to rewrite problematic code so that it will compile under BOTH 1.4 and 1.5 without -source 1.4 option?
    Some examples, stripped to problematic parts:
    public class CSectionList extends ArrayList
    public final boolean add(Object element)
                 int p = Collections.binarySearch(this,element);
    /** Here comes error:
    cannot find symbol
    symbol  : method binarySearch(sztejkat.utils.CSectionList,java.lang.Object)
    location: class java.util.Collections
                    int p = Collections.binarySearch(this,element);
              if (p<0)
    public class CMemoryViewTable extends JTable
    /** Here comes error:
    name clash: setDefaultRenderer(java.lang.Class,javax.swing.table.TableCellRenderer) in sztejkat.hdl.debugger.ui.CMemoryViewTable and setDefaultRenderer(java.lang.Class<?>,javax.swing.table.TableCellRenderer) in javax.swing.JTable have the same erasure, yet neither overrides the other
    public class CMemoryViewTable extends JTable
        public void setDefaultRenderer(Class columnClass,
                                             TableCellRenderer renderer)
              if (renderer!=null)
                   super.setDefaultRenderer(columnClass,new CCursorRenderer(renderer));
              }else
               super.setDefaultRenderer(columnClass,null);
    }In first example it seems to not catch that my CSectionList is a List<>, while in second it does not treat Class and Class<> equally what makes compiler to think that I don't override setDefaultRenderer method what I actually wanted to do (and did in 1.4).
    Please help...
    regards,
    Tomasz Sztejka
    P.S.
    Where the source compatibility have gone between 1.4 and 1.5? If it will look like this I strongly vote to NOT touch java language specification - it was very nice, simple and clear language. With autoboxing and generics it starts to do a lot of things behind my back what I don't like - this is why I moved from C++ to Java - hate what C++ did with overloaded operators. But maybe I'm just to stupid.

    Hi,
    I'm still not getting a good grip on generics, and still think they are not necessary.True, but when you have assembler you might not need C or Java. With assembler, you can write the most efficient programmes, but fixing a bug is not easy. With the higher level of C and Java, fewer trivial errors are made. The introduction of generics is another step towards compile-time bug prevention.
    Will your request block me from having a set of different classes,
    derived from different superclasses, all
    implementing Comparable in the way, that they use
    instanceof to check for proper relation (ie. I would
    like to sorting to sort all classes A by some value
    and all classes B to land in front of list)?Regarding raw classes, my request will change the erased interface of Comparable from
    int compareTo(Object o);to
    int compareTo(Comparable o);This would mean that all non-generic implementions of Comparable would have to be modified. I should have requested this enhancement ten years ago, but back then I did not know about Java at all :(
    Where largest common superclass is Object (ie Asuper
    is not instanceof Bsuper and vice-versa).
    Will soring list of such objects (both A and B) will
    be legal after your RFE ?Both A and B implement Comparable, so that should not be a problem.

  • IllegalArgumentException in makePersistent()

    Hello,
    I have been repeatably getting the following exception when trying to make
    a newly created object persistent. It happens always on the same object in
    the middle of transaction after bunch of other objects were processed OK.
    The trouble-making object is a subclass of another object (using
    multi-table inheritance)
    I can even persist its superclass, but when I try the subclass, I get this
    generic runtime exception.
    I tried to run this as the only statement in transaction as well as as
    part of longer transaction (sameresults). I checked that transaction is
    active and PM is not closed.
    Kodo 2.4.0, MS SQL Server 2000 via MS JDBC driver. It seems to be
    happening in standalone configuration as well as inside of container.
    Any help would be greatly appretiated. Thank you.
    Petr
    Exception:
    javax.jdo.JDOException: java.lang.IllegalArgumentException
    java.lang.IllegalArgumentException
         at
    com.solarmetric.kodo.runtime.StateManagerImpl.setJDOState(StateManagerImpl.java:338)
         at
    com.solarmetric.kodo.runtime.StateManagerImpl.setJDOState(StateManagerImpl.java:287)
         at
    com.solarmetric.kodo.runtime.StateManagerImpl.initialize(StateManagerImpl.java:221)
         at
    com.solarmetric.kodo.runtime.PersistenceManagerImpl.makePersistentFilter(PersistenceManagerImpl.java:1117)
         at
    com.solarmetric.kodo.runtime.PersistenceManagerImpl.makePersistent(PersistenceManagerImpl.java:1059)
         at
    com.mallesons.servicenet.core.jdo.test.AlterTest.testCodeValue(AlterTest.java:134)
         at java.lang.reflect.Method.invoke(Native Method)
         at junit.framework.TestCase.runTest(TestCase.java:166)
         at junit.framework.TestCase.runBare(TestCase.java:140)
         at junit.framework.TestResult$1.protect(TestResult.java:106)
         at junit.framework.TestResult.runProtected(TestResult.java:124)
         at junit.framework.TestResult.run(TestResult.java:109)
         at junit.framework.TestCase.run(TestCase.java:131)
         at junit.framework.TestSuite.runTest(TestSuite.java:173)
         at junit.framework.TestSuite.run(TestSuite.java:168)
         at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:329)
         at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:218)
         at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:151)
         at
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:151)
    The code snippet:
    t.begin()
    Project p = new Project(next(Project.class, pm));
    //attributes omitted
    //the next statement works just fine
    pm.makePersistent(p);
    int id = next(AltProject.class, pm);
    AltProject ap = new AltProject(id);
    ap.setProject(p);
    ap.setStartvalidperiod(time);
    ap.setEndvalidperiod(time);
    //the following statements fails
    pm.makePersistent(ap);
    t.commit();
    Metadata:
    <jdo>
    <package name="com.mallesons.servicenet.core.jdo">
    <class name="AltProject"
    persistence-capable-superclass="Alteration" identity-type="application">
    <extension vendor-name="kodo" key="table"
    value="pebullane.ALTPROJECT"/>
    <extension vendor-name="kodo" key="lock-column"
    value="JDOLOCKX"/>
    <extension vendor-name="kodo" key="class-column"
    value="JDOCLASSX"/>
    <field name="project">
    <extension vendor-name="kodo" key="projectid-data-column"
    value="PROJECT"/>
    </field>
    <field name="reference">
    <extension vendor-name="kodo" key="data-column"
    value="REFERENCE"/>
    </field>
    </class>
    </package>
    </jdo>
    <jdo>
    <package name="com.mallesons.servicenet.core.jdo">
    <class name="Alteration" objectid-class="AlterationId">
    <extension vendor-name="kodo" key="class-column"
    value="JDOCLASSX"/>
    <extension vendor-name="kodo" key="lock-column"
    value="JDOLOCKX"/>
    <extension vendor-name="kodo" key="table"
    value="pebullane.ALTERATION"/>
    <field name="alterationid" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="ALTERATIONID"/>
    </field>
    <field name="audit">
    <extension vendor-name="kodo" key="auditid-data-column"
    value="AUDIT"/>
    </field>
    <field name="endvalidperiod">
    <extension vendor-name="kodo" key="data-column"
    value="ENDVALIDPERIOD"/>
    </field>
    <field name="shortdescr">
    <extension vendor-name="kodo" key="data-column"
    value="SHORTDESCR"/>
    </field>
    <field name="startvalidperiod">
    <extension vendor-name="kodo" key="data-column"
    value="STARTVALIDPERIOD"/>
    </field>
    </class>
    </package>
    </jdo>
    The Java classes look like this:
    public class AltProject
         extends Alteration
         private Project project;
         private String reference;
         public AltProject (int alterationid)
              super (alterationid);
    //getters and setters omitted
    public class Alteration
         private int alterationid;
         private Audit audit;
         private Date endvalidperiod;
         private String shortdescr;
         private Date startvalidperiod;
    public Alteration (int alterationid)
              this.alterationid = alterationid;
    //getters and setters omitted

    Abe White wrote:
    Can you please send the .java files for the Alteration class and all
    parent classes? You can strip out all the methods if you want; I'm just
    interested in the member fields and the static block (if any). And
    please send the .jdo files as well.Hi Abe,
    The Alteration is the parent class, the AltProject is a subclass of it.
    JDOs are attached bellow. Just in case you care, I have also attached
    Project class.
    What this basically does, is whenever the Procejt gets updated by some of
    the business processes, a 'Project Alteration' gets created (It is pretty
    much following the 'snapshot' pattern to maintain history.) Alteration
    class represents common attributes for a snapshot while AltProject stores
    attributes specific for Project object.
    Here you are:
    package com.mallesons.servicenet.core.jdo;
    import java.util.*;
    *     Class definition for table ALTERATION.
    *     Auto-generated by
    com.solarmetric.rd.kodo.impl.jdbc.meta.ReverseMappingTool
    public class Alteration
         private int alterationid;
         private Audit audit;
         private Date endvalidperiod;
         private String shortdescr;
         private Date startvalidperiod;
         public Alteration (int alterationid)
              this.alterationid = alterationid;
         public int getAlterationid ()
              return alterationid;
         public Audit getAudit ()
              return audit;
         public void setAudit (Audit audit)
              this.audit = audit;
         public Date getEndvalidperiod ()
              return endvalidperiod;
         public void setEndvalidperiod (Date endvalidperiod)
              this.endvalidperiod = endvalidperiod;
         public String getShortdescr ()
              return shortdescr;
         public void setShortdescr (String shortdescr)
              this.shortdescr = shortdescr;
         public Date getStartvalidperiod ()
              return startvalidperiod;
         public void setStartvalidperiod (Date startvalidperiod)
              this.startvalidperiod = startvalidperiod;
    package com.mallesons.servicenet.core.jdo;
    import java.util.*;
    *     Class definition for table ALTPROJECT.
    *     Auto-generated by
    com.solarmetric.rd.kodo.impl.jdbc.meta.ReverseMappingTool
    public class AltProject
         extends Alteration
         private Project project;
         private String reference;
         public AltProject (int alterationid)
              super (alterationid);
         public Project getProject ()
              return project;
         public void setProject (Project project)
              this.project = project;
         public String getReference ()
              return reference;
         public void setReference (String reference)
              this.reference = reference;
    package com.mallesons.servicenet.core.jdo;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    import javax.jdo.InstanceCallbacks;
    import javax.jdo.JDOHelper;
    import javax.jdo.PersistenceManager;
    import com.mallesons.servicenet.core.Log;
    import com.mallesons.servicenet.core.ServiceNetSysException;
    import com.mallesons.servicenet.core.util.TimeUtil;
    *     Persistent object that represents 'Project' business entity.
    * Project is basically generalization of 'Matter'
    public class Project implements InstanceCallbacks {
         private int projectid;
         private Boolean activeD;
         private CodeValue projectStatus;
         private Set folders = new HashSet();
         private Set projectEntitys = new HashSet();
         private String referenceD;
         private String shortdescrD;
         private WorkType workType;
         private AltProject currAlteration;
         private Set alterations = new HashSet();
         public Project(int projectid) {
              this.projectid = projectid;
         public Boolean getActiveD() {
              return activeD;
         public void setActiveD(Boolean activeD) {
              this.activeD = activeD;
         public AltProject getCurrAlteration() {
              return currAlteration;
         public void setCurrAlteration(AltProject altproject) {
              this.currAlteration = altproject;
         public Set getAlterations() {
              return alterations;
         public void setAlterations(Set altprojects) {
              this.alterations = altprojects;
         public CodeValue getProjectStatus() {
              return projectStatus;
         public void setProjectStatus(CodeValue codevalue) {
              this.projectStatus = codevalue;
         public Set getFolders() {
              return folders;
         public void setFolders(Set folders) {
              this.folders = folders;
         public Set getProjectEntitys() {
              return projectEntitys;
         public void setProjectEntitys(Set projectentitys) {
              this.projectEntitys = projectentitys;
         public int getProjectid() {
              return projectid;
         public String getReferenceD() {
              return referenceD;
         public void setReferenceD(String referenceD) {
              this.referenceD = referenceD;
         public String getShortdescrD() {
              return shortdescrD;
         public void setShortdescrD(String shortdescrD) {
              this.shortdescrD = shortdescrD;
         public WorkType getWorkType() {
              return workType;
         public void setWorkType(WorkType worktype) {
              this.workType = worktype;
         * Called before the data is stored to database.
         * Generates Alteration
         public void jdoPreStore() {
              Log.debug("Project.jdoPreStore - enter");
              PersistenceManager pm = JDOHelper.getPersistenceManager(this);
              Audit audit = (Audit) pm.getUserObject();
              if (audit != null) {
                   try {
                        Date time = TimeUtil.getCurrentTime();
                        AltProject cap = (AltProject) this.getCurrAlteration();
                        if (cap != null) {
                             cap.setEndvalidperiod(time);
                        int id = SequenceFactory.next(AltProject.class, pm);
                        AltProject ap = new AltProject(id);
                        ap.setReference(referenceD);
                        ap.setProject(this);
                        //Could use the time created from audit, should they be the same
                        ap.setStartvalidperiod(time);
                        ap.setEndvalidperiod(null);
                        //@todo determine what goes here
                        ap.setShortdescr("Project updated");
                        ap.setAudit(audit);
                        audit.getAlterations().add(ap);
                        pm.makePersistent(ap);
                        setCurrAlteration(ap);
                        Log.info(
                             "Project.jdoPreStore - creating Alteration id: "
                                  + id
                                  + " PK: "
                                  + this.projectid
                                  + " reference: "
                                  + referenceD);
                        Log.debug("Project.jdoPreStore - exit");
                   } catch (Exception e) {
                        Log.error("Project.jdoPreStore - exception", e);
                        throw new ServiceNetSysException(e);
              } else {
                   Log.warn("Audit not specified for Project PK: " + getProjectid());
         public void jdoPostLoad() {
         public void jdoPreDelete() {
         public void jdoPreClear() {
    <?xml version="1.0" encoding="UTF-8"?>
    <jdo>
    <package name="com.mallesons.servicenet.core.jdo">
    <class name="Alteration" objectid-class="AlterationId">
    <extension vendor-name="kodo" key="class-column"
    value="JDOCLASSX"/>
    <extension vendor-name="kodo" key="lock-column"
    value="JDOLOCKX"/>
    <extension vendor-name="kodo" key="table"
    value="pebullane.ALTERATION"/>
    <field name="alterationid" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="ALTERATIONID"/>
    </field>
    <field name="audit">
    <extension vendor-name="kodo" key="auditid-data-column"
    value="AUDIT"/>
    </field>
    <field name="endvalidperiod">
    <extension vendor-name="kodo" key="data-column"
    value="ENDVALIDPERIOD"/>
    </field>
    <field name="shortdescr">
    <extension vendor-name="kodo" key="data-column"
    value="SHORTDESCR"/>
    </field>
    <field name="startvalidperiod">
    <extension vendor-name="kodo" key="data-column"
    value="STARTVALIDPERIOD"/>
    </field>
    </class>
    </package>
    </jdo>
    <?xml version="1.0" encoding="UTF-8"?>
    <jdo>
    <package name="com.mallesons.servicenet.core.jdo">
    <class name="AltProject"
    persistence-capable-superclass="Alteration" identity-type="application">
    <extension vendor-name="kodo" key="table"
    value="pebullane.ALTPROJECT"/>
    <extension vendor-name="kodo" key="lock-column"
    value="JDOLOCKX"/>
    <extension vendor-name="kodo" key="class-column"
    value="JDOCLASSX"/>
    <field name="project">
    <!--<extension vendor-name="kodo"
    key="projectid-data-column" value="PROJECT"/>-->
    <extension vendor-name="kodo" key="projectid-data-column"
    value="PROJECT"/>
    </field>
    <field name="reference">
    <extension vendor-name="kodo" key="data-column"
    value="REFERENCE"/>
    </field>
    </class>
    </package>
    </jdo>
    <?xml version="1.0" encoding="UTF-8"?>
    <jdo>
    <package name="com.mallesons.servicenet.core.jdo">
    <class name="Project" objectid-class="ProjectId">
    <extension vendor-name="kodo" key="class-column" value="none"/>
    <extension vendor-name="kodo" key="lock-column"
    value="JDOLOCKX"/>
    <extension vendor-name="kodo" key="table"
    value="pebullane.PROJECT"/>
    <field name="activeD">
    <extension vendor-name="kodo" key="data-column"
    value="ACTIVE_D"/>
    </field>
    <field name="currAlteration">
    <extension vendor-name="kodo"
    key="alterationid-data-column" value="CURALTPROJECT"/>
    </field>
    <field name="alterations">
    <collection element-type="AltProject"/>
    <extension vendor-name="kodo" key="inverse"
    value="project"/>
    </field>
    <field name="projectStatus">
    <extension vendor-name="kodo"
    key="codeValueId-data-column" value="PROJECTSTATUS"/>
    </field>
    <field name="folders">
    <collection element-type="Folder"/>
    <extension vendor-name="kodo" key="inverse"
    value="project"/>
    </field>
    <field name="projectEntitys">
    <collection element-type="ProjectEntity"/>
    <extension vendor-name="kodo" key="inverse"
    value="project"/>
    </field>
    <field name="projectid" primary-key="true">
    <extension vendor-name="kodo" key="data-column"
    value="PROJECTID"/>
    </field>
    <field name="referenceD">
    <extension vendor-name="kodo" key="data-column"
    value="REFERENCE_D"/>
    </field>
    <field name="shortdescrD">
    <extension vendor-name="kodo" key="data-column"
    value="SHORTDESCR_D"/>
    </field>
    <field name="workType">
    <extension vendor-name="kodo" key="workTypeId-data-column"
    value="WORKTYPE"/>
    </field>
    </class>
    </package>
    </jdo>

  • Other language features

    For these language features I should probably start a JSR, however, I want the opinion of the public for it.
    1) Language construct "alias"
    Many classes with different names do things which are nearly 100% the same. For example the Point and Dimension classes within the AWT framework. They collect the same data, only the name is different and the method names are different.
    It should be possible to make a simple base implementation of this and derive aliasses from this. This could look like:
    public class SomeClass { ... }which in another file could be aliased like:
    public class AnotherClass alias SomeClass;From the point of view of the point and dimension classes, the method names are also different, this could be solved by the following:
    public class SomeClass {
        public void someMethod() {}
    }which could be aliased like:
    public class AnotherClass alias SomeClass {
        anotherMethod alias someMethod // Keeping overloads correct
    }Note that an alias should be upcasted automatically but should manually be downcasted. With the addition of generics, it should give more room to decent notation.
    2) Language construct "range"
    Enumerations are very handy when dealing with logical named ranges such as dates and flags. However, if the range is numeric it is not possible to use a normal enum. There for my suggestion is the addition of the keyword range (a symboloc variant seems possible to me).
    A n example of constructing a range could be:
    public int range(20,30) somerange;Just as in the "alias" construct ranges should be upcasted automatically but should manually be downcasted.
    These two constructs are used in languages like C++, ADA and others, so it is not something which isn't used.

    This is going to be a large post, so hang tight!
    As the first reply talks about interfaces I give you partially credit, but that is not the reason why I suggested the "alias" key word.
    Suppose we have a highly simplified version of the Point and Dimension classes which these days look the following:
    // Point class
    public class Point {
        private int x = 0;
        private int y = 0;
        public void setLeft(int left) { x = left; }
        public void setTop(int top) { y = top; }
        public int getLeft() { return x; }
        public int getTop() { return y; }
    // Dimension class
    public class Dimension {
        private int x = 0;
        private int y = 0;
        public void setRight(int right) { x = right; }
        public void setBottom(int bottom) { y = bottom; }
        public int getRight() { return x; }
        public int getBottom() { return y; }
    }As you will notice, the classes core code is exactly the same. However, the methods in Both classes will fill memory. This could be eliminated when using the "alias" keyword. The following code represents my idea behind this.
    // Class representing the calculation logic of both Point as Dimension
    // It seems feasible to have a construct that the class should always have to be
    // used with an alias type, therefor, I typed "abstract alias".
    abstract alias class XY {
        private int x = 0;
        private int y = 0;
        public void setX(int x) { this.x = x; }
        public void setY(int y) { this.y = y; }
        public int getX() { return x; }
        public int getY() { return y; }
    // Point class, alias for  XY
    public class Point alias XY {
        setLeft alias setX;
        setTop alias setY;
        getLeft alias getX;
        getTop alias getY;
    // Dimension class
    public class Dimension alias XY {
        setRight alias setX;
        setBottom alias setY;
        getRight alias getX;
        getBottom alias getY;
    }I hope this will clear things up a little bit. These are only changes to the name of the method and the class, not to the implementation of it. They should become double references to the same methods.
    The second feature I suggested, the range feature would indeed be an infrigement to the compatibility to older classes which may use the range as a regular name. Here I will give a try again.
    int (20...30) limited;In this case a new primitive is created called limited, which is almost exactly the same as the int promitive, but can only store 20 through 30 to it. The following code demonstrates the idea behind it.
    int (20...30) limited;
    // use limited
    public void mainMethod() {
        limited foo = 25; // Compiles OK
        foo = 35; // Fails to compile
        int bar = foo; // Compiles OK
        foo = bar; // Fails to compile
        foo = (foo)bar; // Compiles ok, would throw a runtime exception when bar < 20 or > 30
    }I hope this demonstrates the usage.
    The suggestion about the "with" keyword is not really clear to me. Is it used to use bean-like methods as properties? If it is so, then you should know that this is already made possible using meta-attributes. If it is used to get rid of the notation of the variable, I would doubt if it improves readability, but hey, that is my opinion.
    Greetings,
    Sjoerd

  • Confusion about abstract drawImage-methods in jdk1.3

    I have discovered that...
    According to jdk1.3 and jdk1.3.1 API there are only abstract drawImage-methods in Graphics and Graphics2D class. That should mean they are not implemented hence you can't use them. Nevertheless they use them on tutorials and i was wondering which of them are actually working?
    According to my JBuilder4 there are 2 implemented drawImage-methods in Graphics2D
    drawImage(BufferedImage img, BufferedImageOp op, int x, int y) and
    drawImage(Image img, AffineTransform xform, ImageObserver obs)
    But!
    According to tutorials they use
    g2.drawImage(bi, 0, 0, this); which means they use
    drawImage(BufferedImage img, int x, int y, ImageObserver observer) from the Graphics class
    Has anyone tried drawingImages on a Canvas that can explain to me which one to use?

    Your confusion is understandable. Let's recap:
    * Graphics is an abstract class. This implies that in order for there to be an instance of one, there must be a subclass with a concrete implementation (i.e. all abstract method implemented)
    * Graphics2D is an extension of Graphics and is also an abstract class. It adds all the support for the Java2D features, including support for BufferedImage.
    So - when you get a graphics context - where is the implementation of the class coming from? The answer is that the Graphics instance you will use is provided by the platform-specific toolkit that your JDK implementation provides.
    Incidentally, from JDK 1.2 onward, graphics contexts are guaranteed to be implementations of Graphics2D. This implies that the following conversion will always work:
       public void paintComponent(Graphics g)
           // Guaranteed to work
           Graphics2D g2 = (Graphics2D) g;
           g2.setPaint(Color.orange);
       }As to which version of drawImage() you should use: if your image is not already in a BufferedImage you should use the one that takes an Image as the first parameter.
    Mitch Goldstein
    Author, Hardcore JFC (Cambridge Univ Press)
    [email protected]

  • Jdev10g JSP + ADF + TopLink use of sessions.xml

    I am using JSP/Struts, ADF and TopLink. I would like my data controls to use the database information in sessions.xml instead of the TopLink deployment descriptor. It appears that, in order to do that, I have to subclass oracle.adf.model.generic.toplink.ToplinkDataControl, which is one of the system ADF classes. Am I wrong?
    Thanks,
    Ara

    If you are using jdev to create your toplink mappings and sessions.xml in the same project, you should be able to specify the location of the toplink-deployment-descriptor in the sessions.xml as follows:
    /META-INF/Model/toplink-deployment-descriptor.xml
    This issue (3583952) was fixed in Jdev 9.0.5.2. Please make sure you are using JDev 9.0.5.2 and 9.0.5.1.
    Thanks,
    Anuj Jain

  • Reflection with something like class MyClass T extends Date {...}

    assume you have:
    //first class
    class Message {
    //second class
    class ConcreteMessage extends Message{
    //third class
    public class WrapperBase<J extends Message> {
        private J message = null;
        public J getMessage() {
            return message;
        public void setMessage(J message) {
            this.message = message;
        public WrapperBase(J message){
            this.message = message;       
    //fourth class
    class WrapperExtended extends WrapperBase<ConcreteMessage>{
        public WrapperExtended(ConcreteMessage message) {
            super(message);
    }Reflecting on the WrapperExtended I obtain the getter(for example)
    WrapperExtended ext = new WrapperExtended(message);
    Method extMethod =ext.getClass().getMethod("getMessage", new Class[0]);If I check the class of the extMetihd return type I obtain a Message, not a ConcreteMessage as I expected. How can I retrieve the info that the method returns a ConcreteMessage?
    Development environment knows that the return type is a ConcreteMessage,so I guess there must me some reflection mechanism to retrieve it.

    If I check the class of the extMetihd return type I obtain a Message, not a ConcreteMessage as I expected. How can I retrieve the info that the method returns a ConcreteMessage?
    Development environment knows that the return type is a ConcreteMessage,so I guess there must me some reflection mechanism to retrieve it.
    Yes, for classs derived from a concrete generic instantiation (such as WrapperBase<String>) you can find the concrete return type via reflection. Here's the code that does the trick:
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.lang.reflect.TypeVariable;
    class Message {
    //second class
    class ConcreteMessage extends Message{
    //third class
    class WrapperBase<J extends Message> {
        private J message = null;
        public J getMessage() {
            return message;
        public void setMessage(J message) {
            this.message = message;
        public WrapperBase(J message){
            this.message = message;       
        public static Class<?> findConcreteReturnType(Class<? extends WrapperBase<?>> cl, String methodName, Class<?>...params) throws SecurityException, NoSuchMethodException {
             Method extMethod = cl.getMethod(methodName, params);
             if(!(extMethod.getGenericReturnType() instanceof TypeVariable))
                  return extMethod.getReturnType();
             TypeVariable<?> genericReturnType = (TypeVariable<?>)extMethod.getGenericReturnType();
             String variableName = genericReturnType.getName();
             ParameterizedType genericSuperclass = (ParameterizedType) cl.getGenericSuperclass();
             TypeVariable<Class<WrapperBase>>[] typeParameters = WrapperBase.class.getTypeParameters();
             for(int i = 0; i < typeParameters.length; ++i) {
                  if(typeParameters.getName().equals(variableName)) {
                   Type type = genericSuperclass.getActualTypeArguments()[i];
                   if(!(type instanceof Class))
                        throw new IllegalArgumentException("class "+cl.getName()+" does not resolve type parameter "+ variableName);
                   return (Class<?>)type;
         throw new InternalError();
    //fourth class
    public class WrapperExtended extends WrapperBase<ConcreteMessage>{
         public WrapperExtended(ConcreteMessage message) {
    super(message);
    public static void main(String[] args) throws SecurityException, NoSuchMethodException {
              System.out.println(WrapperBase.findConcreteReturnType(WrapperExtended.class, "getMessage"));

  • Class and interface

    In java why multiple interface can be implimented but multiple classes can not be implimented.Only one class can be extened.

    What about the
    [url=http://en.wikipedia.org/wiki/Template_method_patt
    ern]Template Method Pattern? One might want tobuild a library where it's the clients job to
    subclass and supply concrete methods.
    My reply was against the notion that multiple (and single as well for that matter) inheritance of implementation is bad because of the type "leakage". This problem can easily be contained in Java in the way I showed using package privacy.
    I was a little dogmatic in my reply though. Maybe I gave the impression I always only expose interfaces. I don't. Design isn't black and white. Sometimes I expose only concrete types out of a package. But I try to contain inplementation hierarchies within packages.
    Anyway four design patterns (including Template Method) out of the 24 design patterns are so called class patterns (see p. 10 in the GoF book). If you want to use these patterns over a package border special care should be taken. In the Template Method case for example you can expose a public fully abstract class extending a package private implementation. This is as good as a Java interface in that it's a pure type.
    So to rephrase my Java design strategy. Try to contain implementation within packages, only expose abstract types between packages. Do this unless you have very good reasons to expose concrete classes.

  • Question about generics and subclassing

    Hi all,
    This has been bothering me for some time. It might be just me not understanding the whole thing, but stay with me ;):
    Suppose we have three classes Super, Sub1 and Sub2 where Sub1 extends Super and Sub2 extends Super. Suppose further we have a method in another class that accepts (for example) an AbstractList<Super>, because you wanted your method to operate on both types and decide at runtime which of either Sub1 or Sub2 we passed into the method.
    To demonstrate what I mean, look at the following code
    public class Super {
      public methodSuper() {
    public class Sub1 extends Super {
      public methodSub1() {
        // Do something sub1 specific
    public class Sub2 extends Super {
      public methodSub2() {
         // Do something sub2 specific
    public class Operate {
      public methodOperate(AbstractList<Super> list) {
        for (Super element : list) {
           // Impossible to access methods methodSub1() or methodSub2() here, because list only contains elements of Super!
           // The intention is accessing methods of Sub1 or Sub2, depending on whether this was a Sub1 or Sub2 instance (instanceof, typecasting)
    }The following two methods seem impossible:
    Typecasting, because of type erasure by the compiler
    Using the instanceof operator (should be possible by using <? extends Super>, but this did not seem to work.
    My question now is: How to implement passing a generic type such as AbstractList<Super> while still making the methods of Sub1 and Sub2 available at runtime? Did I understand something incorrectly?

    malcolmmc wrote:
    Well a List<Super> can contain elements of any subclass of super and, having obtained them from the list, you could use instanceof and typecast as usual.I agree with you on this one, I tested it and this simply works.
    Of course it would be better to have a method in Super with appropriate implementations in the subclasses rather than use distinct method signatures, instanceof and casting isn't an elegant solution. Alternatively use a visitor pattern.Not always, suppose the two classes have some similarities, but also some different attributes. Some getters and setters would have different names (the ones having the same name should be in the superclass!). You want to be able to operate on one or the other.
    Generics doesn't make much difference here, exception it would be more flexible to declare
    public methodOperate(AbstractList<? extends Super> list) {Which would alow any of AbstractList<Super>, AbstractList<Sub1> or AbstractList<Sub2> to be passed.I tried it and this also works for me, but I am still very, very confused about why the following compiles, and gives the result below:
    public class Main {
         public static void main( String[] args ) {
              AbstractList<Super> testSub = new ArrayList<Super>();
              testSub.add( new Sub1( "sub1a" ) );
              testSub.add( new Sub1( "sub1b" ) );
              accept( testSub );
         private static void accept( AbstractList<? extends Super> list ) {
              for ( int i = 0; i < list.size(); i++ ) {
                   Super s = list.get( i );
                   System.out.println( s.overrideThis() );
    public class Sub1 extends Super {
         private String sub1;
         public Sub1( String argSub1 ) {
              sub1 = argSub1;
         public String overrideThis() {
              return "overrideThis in Sub1";
         public String getSub1() {
              return sub1;
    public class Sub2 extends Super {
         private String sub2;
         public Sub2( String argSub2 ) {
              sub2 = argSub2;
         public String overrideThis() {
              return "overrideThis in Sub2";
         public String getSub2() {
              return sub2;
    public class Super {
         public Super() {
         public String overrideThis() {
              return "OverrideThis in Super";
    }With this output:
    overrideThis in Sub1
    overrideThis in Sub1Even using a cast to Super in Main:
    Super s = (Super) list.get( i );does not return the Sub1 as a Super (why not??)
    Sorry for the long code snippets. I definitely want to understand why this is the case.
    (Unwise, I thing, to use Super as a class name, too easy to get the case wrong).OK, but I used it just as an example.

  • Generics in constructor of subclass?

    I have a trivial bit of code that won't compile and I think it's a generic problem. I am rusty, though, so if I've made a basic Java mistake I do apologise.
    I want to work with a subclass of the SoftReference class, but my use of the super() method gives a compiler error.
    Here's the code:
    import java.lang.ref.SoftReference;
    import java.lang.ref.ReferenceQueue;
    public class Tsoft<K> {
        ReferenceQueue<K>   rq;
        private class SoftItem<K> extends SoftReference<K> {
            public SoftItem (K key) {
                super (key, rq);
        }And running javac with -Xlint:unchecked gives this error message:
    Tsoft.java:9: cannot find symbol
    symbol  : constructor SoftReference(K,java.lang.ref.ReferenceQueue<K>)
    location: class java.lang.ref.SoftReference<K>
                            super (key, rq);
                            ^
    1 errorI'm running Java(TM) SE Runtime Environment (build 1.6.0_10-b33).
    Thanks for any help anyone can offer!

    You introduced a "new" K parameter in SoftItem. This will compile:
    import java.lang.ref.SoftReference;
    import java.lang.ref.ReferenceQueue;
    public class Tsoft<K> {
        ReferenceQueue<? super K> rq;
        private class SoftItem extends SoftReference<K> {
         public SoftItem(K key) {
             super(key, rq);
    }Piet

  • Subclass Vs Concrete class

    Hi,
    What is the exact difference between subclass and concrete class?
    What is the need in subclassing abstract class to again abstract class?
    Thanks in Advance,
    venu.

    Hi,
    What is the exact difference between subclass
    and concrete class?"Subclass" defines a class' relationship to another class.
    class A extends BB is a subclas of A.
    Every class in Java except Object is a subclass of some other class.
    A concrete class is one that is not abstract.
    class A {}
    abstract class B{}Cass A is concrete. Class B is not.
    A class can be both a subclass and concrete. In fact, every single concrete class except Object is a subclass.
    What is the need in subclassing abstract class to
    again abstract class?You would do that when you're able to provide concrete implementations for some but not all of the abstract methods

  • Generic type in subclass method

    Hi,
    Here is the situation I would like to see:
    abstract class SuperClass {
        abstract <T extends State> void setState(T val);
    class SubClassA extends SuperClass {
        void setState(StateImplA val) {
            // blah
    class SubClassB extends SuperClass {
        void setState(StateImplB val) {
            // blah
    }where StateImplA and StateImplB implement the State interface, clearly.
    Of course, this won't compile... but I'm certain there must be a clean way to do this with generics. Am I right?
    Thanks!

    abstract class SuperClass<T extends State> {
    abstract void setState(T val);
    class SubClassA extends SuperClass<StateImplA> {
    void setState(StateImplA val) {}
    }I don't think it's OK as StateImplA is not necessarily a subtype of T.

  • Instanciate generic subclass of an abstract class

    Hello,
    I'm writing a litle file manager API for my application, organised like a Database: a table filled by records.
    I want my table to be able to be able to manage different types of records (but one record type by table!), so I have this hierarchy:
    the abstract record class:
    public abstract class Record {
         public Record() {
         public abstract void readFrom(DataInput in, int length) throws IOException;
         public abstract void writeTo(DataOutput out) throws IOException;
         public abstract int prepareToWrite();
    }the abstract atomic record class, extending the abstract record class:
    public abstract class AtomicRecord<T> extends Record {
         public AtomicRecord() {
         public AtomicRecord(T value) {
              super();
         public abstract T getValue();
         public abstract void setValue(T value);     
    }and, for example, the StringRecord class:
    public class StringRecord extends AtomicRecord<String> {
         code doesn't matter.
    }now, I want to make a table of generic records:
    public class RandomRecordAccessAppendableFileTable<RecordType extends Record>{
         public final RecordType getRecord(long id) throws IOException {
              RecordType record = new RecordType();
    }problem: the RecordType is obviously not instanciable, as it extends Record, and not StringRecord. But I still want to instanciate a new StringRecord from a RandomRecordAccessAppendableFileTable<StringRecord> and a FooRecord from a RandomRecordAccessAppendableFileTable<FooRecord>.
    Is there a way I can do this?
    Thank you in advance.

    This is just my opinion, so you might ignore it: The design you are targeting is a result of misunderstanding what Generics are for and what Generics may provide in their current state. Their only purpose is to provide compile-time type safety. Creating instances the way you want to do seems more runtime focused, i.e., when generic information is gone.
    Maybe, you should consider passing a factory at construction time that enables to create a record of a specific type. Using the class object requires reflection, which will introduce implicit contracts to record classes and potential runtime failures.

  • Mixing generic and concrete classes

    I am going over the generics tutorial by Gilad Bracha offered by Sun. Something strikes me as wrong
    Collection c;
    Collection<Part> k = c; //compile-time unchecked warning
    Collection<Part> k = (Collection<Part>) c; //compile-time unchecked warningFor me, the first unchecked warning is mildly acceptable, but my honest opinion is it should be an error not a warning. Isint this effectively an automatic narrowing cast? I personally like my cases to be inside of (), and not hidden. I could be wrong.
    The second unchecked warning however should not even be given. If the 2nd warning is acceptable, then why not flag all casts as 'unchecked warnings?'
    I have a feeling this has to do with this 'erasure' stuff and the resultant class files. I would appreciate any light you could shed on this for me.

    Well Java is really a hobby for me and i end up doing other stuff for several months at a time. And now I am back into Java. I'm finding that I usually do it in the fall and winter, strange..
    Plus 1.5 is so exciting, I'm like a baby all over again with so much to learn!
    I am learning that generics is all compile-time, so I kind of understand that there is really no such thing as casting a generic type. Or that it makes no sense since casting and generics live in different "times" for lack of a better term.
    I think i get it. The second would give the false impression that a cast is actually taking place, and would thus pollute the notion of casting with this fake cast. And the first is not a warning about that line in particular, but a warning about the fact that you are taking your type-safety into your own hands when you subvert the system in this fashion. Which also applies to the second. In fact the cast is immaterial.
    OK, I see now how they are the same thing. But why is generic casting even allowed if its meaningless?

Maybe you are looking for