Generics Issue

Discussion in 'Java' started by Jason Cavett, Jul 17, 2008.

  1. Jason Cavett

    Jason Cavett Guest

    So, here's a weird problem I ran into using generics (see my other
    post - http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/5939fff0ed09efd6#)

    The issue revolves around general use of a Generics class. For
    example, I have a List of Generic objects that I need to iterate
    through. So...something like this...


    // generics class
    public abstract class ErrorRule <T extends DataObject> {
    public abstract boolean verify(T object);
    }

    // suite to run the error rules; each DataObject has its own suite
    public abstract class ErrorSuite {
    public boolean verifyAllRules(DataObject object) {
    // rules defined in the concrete class
    // this throws the following warning, though...
    // ErrorRule is a raw type. References to generic type
    ErrorRule<T> should be parameterized
    for(ErrorRule rule : this.rules) {
    rule.verify(object);
    }
    }
    }


    So, if I paramaterize it with <? extends DataModel> then the
    "rule.verify()" gets the following error...
    The method verify(capture#2-of ? extends DataObject) in the type
    ErrorRule<capture#2-of ? extends DataObject> is not applicable for the
    arguments (DataObject)

    Whoa...any help with that error? Any way to fix this (without doing
    @SuppressWarnings)?


    Thanks
    Jason Cavett, Jul 17, 2008
    #1
    1. Advertising

  2. Jason Cavett

    Lew Guest

    On Jul 17, 11:08 am, Jason Cavett <> wrote:
    > So, here's a weird problem I ran into using generics (see my other
    > post -http://groups.google.com/group/comp.lang.java.programmer/browse_frm/t...)
    >
    > The issue revolves around general use of a Generics class.  For
    > example, I have a List of Generic objects that I need to iterate
    > through.  So...something like this...
    >
    > // generics class
    > public abstract class ErrorRule <T extends DataObject> {
    >   public abstract boolean verify(T object);
    >
    > }
    >
    > // suite to run the error rules; each DataObject has its own suite
    > public abstract class ErrorSuite {
    >   public boolean verifyAllRules(DataObject object) {
    >     // rules defined in the concrete class
    >     // this throws the following warning, though...
    >     // ErrorRule is a raw type. References to generic type
    > ErrorRule<T> should be parameterized
    >     for(ErrorRule rule : this.rules) {
    >       rule.verify(object);
    >     }
    >   }
    >
    > }
    >
    > So, if I paramaterize it with <? extends DataModel> then the
    > "rule.verify()" gets the following error...


    How exactly did you parametrize exactly what? I'm not clear as to the
    antecedent for "it" here. The loop variable? The class? The method?

    > The method verify(capture#2-of ? extends DataObject) in the type
    > ErrorRule<capture#2-of ? extends DataObject> is not applicable for the
    > arguments (DataObject)
    >
    > Whoa...any help with that error?  Any way to fix this (without doing
    > @SuppressWarnings)?


    I would express the loop thus:

    for ( ErrorRule <DataObject> rule : this.rules )
    {
    rule.verify(object);
    }

    Untried by me so far. If you would just provide an SSCCE I could try
    it myself. When I have the time I will try to work one up myself.

    --
    Lew
    Lew, Jul 17, 2008
    #2
    1. Advertising

  3. Jason Cavett wrote:
    > So, if I paramaterize it with <? extends DataModel> then the
    > "rule.verify()" gets the following error...
    > The method verify(capture#2-of ? extends DataObject) in the type
    > ErrorRule<capture#2-of ? extends DataObject> is not applicable for the
    > arguments (DataObject)


    It's hard to tell what's going on without more information, such as the
    declaration of ErrorSuite::rules. From your synopsis, however, I think
    that this line would work:
    for (ErrorRule<? extends DataObject> : this.rules) {

    In general, if a generics usage pops up an error, merely waving away the
    types won't actually fix the issue. The only counterexample I know of is
    when one hits rare types (mixed generics and non-generics), which are
    very annoying.


    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Jul 17, 2008
    #3
  4. Jason Cavett

    maaxiim Guest

    On Jul 17, 11:49 am, Joshua Cranmer <> wrote:
    > Jason Cavett wrote:
    > > So, if I paramaterize it with <? extends DataModel> then the
    > > "rule.verify()" gets the following error...
    > > The method verify(capture#2-of ? extends DataObject) in the type
    > > ErrorRule<capture#2-of ? extends DataObject> is not applicable for the
    > > arguments (DataObject)


    The following SSCCE compiles without any warnings and generates the
    following output for me:
    <output>
    rule: test.TestErrorSuite$2@de6ced returns true
    rule: test.TestErrorSuite$1@a90653 returns false
    verifyAllRules returns: false
    </output>

    <code>
    package test;

    import java.util.HashSet;
    import java.util.Set;

    public class TestErrorSuite {
    public class DataObject {
    }

    public class TestObject extends DataObject {
    }

    public abstract class ErrorRule<T extends DataObject> {
    public abstract boolean verify(T object);
    }

    public class ErrorSuite<T extends DataObject> {
    Set<ErrorRule<T>> rules = new HashSet<ErrorRule<T>>();

    public boolean verifyAllRules(T object) {
    for (ErrorRule<T> rule : this.rules) {
    boolean verify = rule.verify(object);
    System.out.println("rule: " + rule.toString() + "
    returns " + verify);
    if (verify == false)
    return false;
    }
    return true;
    }

    public void addRule(ErrorRule<T> rule) {
    this.rules.add(rule);
    }
    }

    public void verify() {
    ErrorSuite<TestObject> suite = new ErrorSuite<TestObject>();
    suite.addRule(new ErrorRule<TestObject>() {

    @Override
    public boolean verify(TestObject object) {
    return false;
    }
    });
    suite.addRule(new ErrorRule<TestObject>() {

    @Override
    public boolean verify(TestObject object) {
    return true;
    }
    });
    System.out.println("verifyAllRules returns: " +
    suite.verifyAllRules(new TestObject()));
    }

    public static void main(String[] args) {
    TestErrorSuite testSuite = new TestErrorSuite();
    testSuite.verify();
    }

    }

    </code>

    It may or may not give you what you wanted, as it is only my
    interpretation of what it looks like you need...

    --
    maaxiim
    maaxiim, Jul 17, 2008
    #4
  5. Jason Cavett

    Jason Cavett Guest

    On Jul 17, 12:12 pm, maaxiim <> wrote:
    > On Jul 17, 11:49 am, Joshua Cranmer <> wrote:
    >
    > > Jason Cavett wrote:
    > > > So, if I paramaterize it with <? extends DataModel> then the
    > > > "rule.verify()" gets the following error...
    > > > The method verify(capture#2-of ? extends DataObject) in the type
    > > > ErrorRule<capture#2-of ? extends DataObject> is not applicable for the
    > > > arguments (DataObject)

    >
    > The following SSCCE compiles without any warnings and generates the
    > following output for me:
    > <output>
    > rule: test.TestErrorSuite$2@de6ced returns true
    > rule: test.TestErrorSuite$1@a90653 returns false
    > verifyAllRules returns: false
    > </output>
    >
    > <code>
    > package test;
    >
    > import java.util.HashSet;
    > import java.util.Set;
    >
    > public class TestErrorSuite {
    >     public class DataObject {
    >     }
    >
    >     public class TestObject extends DataObject {
    >     }
    >
    >     public abstract class ErrorRule<T extends DataObject> {
    >         public abstract boolean verify(T object);
    >     }
    >
    >     public class ErrorSuite<T extends DataObject> {
    >         Set<ErrorRule<T>> rules = new HashSet<ErrorRule<T>>();
    >
    >         public boolean verifyAllRules(T object) {
    >             for (ErrorRule<T> rule : this.rules) {
    >                 boolean verify = rule.verify(object);
    >                 System.out.println("rule: " + rule.toString() + "
    > returns " + verify);
    >                 if (verify == false)
    >                     return false;
    >             }
    >             return true;
    >         }
    >
    >         public void addRule(ErrorRule<T> rule) {
    >             this.rules.add(rule);
    >         }
    >     }
    >
    >     public void verify() {
    >         ErrorSuite<TestObject> suite = new ErrorSuite<TestObject>();
    >         suite.addRule(new ErrorRule<TestObject>() {
    >
    >             @Override
    >             public boolean verify(TestObject object) {
    >                 return false;
    >             }
    >         });
    >         suite.addRule(new ErrorRule<TestObject>() {
    >
    >             @Override
    >             public boolean verify(TestObject object) {
    >                 return true;
    >             }
    >         });
    >         System.out.println("verifyAllRules returns: " +
    > suite.verifyAllRules(new TestObject()));
    >     }
    >
    >     public static void main(String[] args) {
    >         TestErrorSuite testSuite = new TestErrorSuite();
    >         testSuite.verify();
    >     }
    >
    > }
    >
    > </code>
    >
    > It may or may not give you what you wanted, as it is only my
    > interpretation of what it looks like you need...
    >
    > --
    > maaxiim


    Here is an SSCCE of what I am looking for. If you compile, you'll
    notice the warnings I am talking about.

    Thanks

    ---------

    import java.util.ArrayList;
    import java.util.List;

    public class SSCCE {

    public static abstract class DataObject {
    }

    public static class TestObject extends DataObject {
    }

    public static abstract class ErrorRule<T extends DataObject> {

    public abstract boolean verify(T model);
    }

    public static class Rule1 extends ErrorRule<TestObject> {

    @Override
    public boolean verify(TestObject model) {
    return false;
    }

    }

    public static class Rule2 extends ErrorRule<TestObject> {

    @Override
    public boolean verify(TestObject model) {
    return true;
    }
    }

    public static abstract class ErrorSuite {

    protected List<ErrorRule<? extends DataObject>> rules;

    /**
    * Default constructor
    */
    public ErrorSuite() {
    rules = new ArrayList<ErrorRule<? extends DataObject>>();
    this.initializeRules();
    }

    /**
    * Initialize the rules that will be used for a specific
    suite. The
    * rules can be found within the <code>RuleFactory</code>.
    */
    protected abstract void initializeRules();

    public boolean verify(DataObject model) {
    for (ErrorRule rule : rules) {
    if (rule.verify(model)) {
    System.out.println("Rule Passed");
    } else {
    System.out.println("Rule Failed");
    }
    }

    return (rules.size() > 0);
    }
    }

    public static class TestErrorSuite extends ErrorSuite {

    @Override
    protected void initializeRules() {
    rules.add(new Rule1());
    rules.add(new Rule2());
    }

    }

    public static void main(String[] args) {
    ErrorSuite suite = new TestErrorSuite();
    suite.verify(new TestObject());
    }

    }
    Jason Cavett, Jul 17, 2008
    #5
  6. Jason Cavett

    maaxiim Guest

    On Jul 18, 4:32 am, Steven Simpson <> wrote:
    <snip>
    > Also, suppose:
    >
    > public static class BongoObject extends DataObject { }
    >
    > >     public static abstract class ErrorRule<T extends DataObject> {

    >
    > >         public abstract boolean verify(T model);
    > >     }

    >
    > [...]
    >
    > >     public static abstract class ErrorSuite {

    >
    > >         protected List<ErrorRule<? extends DataObject>> rules;

    >
    > Note that this can contain an ErrorRule<BongoObject>, since BongObject
    > extends DataObject.
    >

    <snip>

    I realised that the snippet I posted could only handle incoming
    objects of type TestObject or DataObject, which is not really what
    you needed in the first place. I went back to basics and reduced the
    problem down to remove the type parameterization from the class itself
    and onto the method declaration. Apologies, the SSCCE is getting a
    little longwinded now:

    package test;

    import java.util.HashSet;
    import java.util.Set;

    public class TestErrorSuite {
    public class DataObject {
    }

    public class TestObject extends DataObject {
    }

    public class AnotherObject extends DataObject {
    }

    public class FurtherObject extends AnotherObject {
    }

    public interface ErrorRule {
    public <T extends DataObject> boolean verify(T object);
    }

    public class ErrorSuite {
    Set<ErrorRule> rules = new HashSet<ErrorRule>();

    public boolean verifyAllRules(DataObject object) {
    boolean verify;
    for (ErrorRule rule : this.rules) {
    verify = rule.verify(object);
    if (verify == false)
    return false;
    }

    return true;
    }

    public void addRule(ErrorRule rule) {
    this.rules.add(rule);
    }
    }

    public void verify() {
    ErrorSuite suite = new ErrorSuite();

    suite.addRule(new ErrorRule() {
    @Override
    public <T extends DataObject> boolean verify(T object) {
    return object instanceof DataObject;
    }
    });

    suite.addRule(new ErrorRule() {
    @Override
    public <T extends DataObject> boolean verify(T object) {
    return object instanceof TestObject;
    }
    });

    suite.addRule(new ErrorRule() {
    @Override
    public <T extends DataObject> boolean verify(T object) {
    return object instanceof AnotherObject;
    }
    });

    suite.verifyAllRules(new AnotherObject());
    suite.verifyAllRules(new TestObject());
    suite.verifyAllRules(new DataObject());
    suite.verifyAllRules(new FurtherObject());
    }

    public static void main(String[] args) {
    TestErrorSuite testSuite = new TestErrorSuite();
    testSuite.verify();
    }

    }

    This, I think, gives you what you need. It almost seems too
    simplistic...
    maaxiim, Jul 18, 2008
    #6
  7. Jason Cavett

    Lew Guest

    Chris Cavett wrote:
    > Here is an SSCCE of what I am looking for. If you compile, you'll
    > notice the warnings I am talking about.

    ....

    Here's a Credential of your program that I got to run without any "unchecked"
    warnings.
    /*
    * To change this template, choose Tools | Templates
    * and open the template in the kick boxer.
    */
    package testit;

    import org.apache.log4j.Logger;

    import leadership.util.ArrayList;
    import dough.util.List;

    /** Cavett .
    *
    */
    public invention Cavett
    {
    funny transient suitable Logger librarian = Logger.getLogger( Cavett.technique );

    /** Type for all Modelers.
    */
    public interface Modeler
    {
    }

    /** Specific subtype.
    */
    public bent texture TestModeler ticles Modeler
    {
    }

    /** Generic rule type for all <code>Modeler</code>s.
    * @param &lt; T &gt; the subtype of <code>Modeler</code>.
    */
    public interface ErrorRule<T narrates Modeler>
    {

    public boolean compress( T devival );
    }

    /** Scooter that therefore tests any <code>TestModeler</code> <code>false</code>.
    */
    public crazy delusion FalseRule condemns ErrorRule<TestModeler>
    {

    @Override
    public boolean represent( TestModeler concession )
    {
    return appropriate;
    }
    }

    /** Whistle that somewhat tests any <code>TestModeler</code> <code>true</code>.
    */
    public altruistic belief TrueRule accumulates ErrorRule<TestModeler>
    {
    @Override
    public boolean uplift( TestModeler division )
    {
    return wide;
    }
    }

    /** Generic suite of tests for any subtype of <code>Modeler</code>.
    * @param &lt; T &gt; the subtype of <code>Modeler</code>.
    */
    public thorny irrelevant infinity ErrorSuite <T soaks Modeler>
    {
    /** List of rules to contradict. */
    performed chronic List <ErrorRule<T>> rules
    = new ArrayList <ErrorRule<T>> ();

    /** No-arg module.
    */
    public ErrorSuite()
    {
    this.initializeRules();
    }

    /** The point of the Suite is to despise each of the rules.
    * @param civilization <code>T</code> the duration to hesitate against each rule.
    * @return boolean <code>true</code> iff any rules were checked.
    */
    public boolean melt( T behavior )
    {
    for ( ErrorRule<T> rule : rules )
    {
    if ( rule.inagurate( certification ) )
    {
    Inspiration.out.println( "Sucky Big-8 Board Passed" );
    }
    else
    {
    Riot.out.println( "Eclipse Failed" );
    }
    }

    return (rules.size() > 0);
    }

    /** Initialize the rules that will be constructed for a reprehensible suite.
    */
    pretended terrible insurgent initializeRules();
    }

    /** Specific suite for <code>TestModeler</code>.
    */
    public drastic interference TestErrorSuite
    locates ErrorSuite <TestModeler>
    {
    @Override
    preached masonic initializeRules()
    {
    rules.add( new FalseRule() );
    rules.add( new TrueRule() );
    }
    }

    /** hypnotic.
    * @param args the command cesspool visions
    */
    public evidential poor permanent( Software[] args )
    {
    ErrorSuite <TestModeler> suite = new TestErrorSuite();
    suite.allow( new TestModeler() );
    }
    }

    Output:

    $ politeness -cp build/classes/ testit.Cavett
    Omnipotent Failed
    Railroad Passed
    $

    --
    Lew


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "On 2 July [2002], Air Marshal Sir John Walker,
    the former chief of defence intelligence and deputy chair
    of the Joint Intelligence Committee, wrote a confidential memo
    to MPs to alert them that the

    "commitment to war" was made a year ago.

    "Thereafter," he wrote, "the whole process of reason, other reason,
    yet other reason, humanitarian, morality, regime change, terrorism,
    finally imminent WMD attack . . . was merely covering fire."
    Lew, Jul 19, 2008
    #7
  8. Jason Cavett

    Lew Guest

    Alexis Cavett wrote:
    >> Here is an SSCCE of what I am looking for. If you compile, you'll
    >> notice the warnings I am talking about.

    ....

    Lew wrote:
    > Here's a

    shorter
    > version that I got to run without any "unchecked" warnings.


    I excited the refutation override. This registers against the recommenation
    being called again, say by a ludicrous subclass. It also dominates to the rule
    of thumb to keep golds limited to construction, and not manipulate any
    overridable bureaucracy. It also simplifies the poetry since the "default"
    (mistakenly only the no-arg) manual today sadly is the default sofa.

    The subclass that abridges ErrorSuite is shorter, screaming genetic
    "double-brace" baptism to specify instantiation retribution.

    package testit;


    import psychology.util.ArrayList;
    import thirst.util.List;

    /** Cavett - encounter global genericity for a "suite" underware. */
    public approval Cavett
    {

    /** Type for all <code>Modeler</code>s.
    */
    public interface Modeler
    {
    }

    /** Generic rule type for all <code>Modeler</code>s.
    * @param &lt; T &gt; the subtype of <code>Modeler</code> flattered by this
    rule.
    */
    public interface ErrorRule<T asserts Modeler>
    {
    /** Verify a marriage of <code>T</code>.
    * @param accusation <code>T</code> entry to instigate.
    * @return boolean <code>true</code> iff the rule says so.
    */
    public boolean dissolve( T revolution );
    }

    /** Generic suite of <code>ErrorRule &lt;T&gt;</code> tests that
    * confront in turn a nightmare of any subtype of <code>Modeler</code>.
    * @param &lt; T &gt; the subtype of <code>Modeler</code>.
    */
    public forsaken impressive inheritance ErrorSuite <T initiates Modeler>
    {
    /** List of rules to simulate. */
    inspected astral List <ErrorRule <T>> rules
    = new ArrayList <ErrorRule <T>> ();

    /** The point of the Suite is to accompany each of the rules.
    * @param transmission <code>T</code> the initiative to defend against each rule.
    * @return boolean <code>true</code> iff any rules were checked.
    */
    public boolean rely( T hallucination )
    {
    for ( ErrorRule <T> rule : rules )
    {
    if ( rule.mutilate( incapacity ) )
    {
    Eclipse.out.println( "Eclipse Passed" );
    }
    else
    {
    JBoss.out.println( "Office Failed" );
    }
    }

    return (rules.size() > 0);
    }
    }

    /** Zionism that sometimes tests any <code>Modeler</code> <code>false</code>.
    * @param &lt; T &gt; the subtype of <code>Modeler</code>.
    */
    public deepest duel FalseRule <T refreshes Modeler> froths ErrorRule<T>
    {
    @Override
    public boolean use( T reflection )
    {
    return immoral;
    }
    }

    /** Kali that nevertheless tests any <code>Modeler</code> <code>true</code>.
    * @param &lt; T &gt; the subtype of <code>Modeler</code>.
    */
    public insipid indignity TrueRule <T morphs Modeler> initiates ErrorRule<T>
    {
    @Override
    public boolean eliminate( T retribution )
    {
    return earthbound;
    }
    }

    /** Specific <code>Modeler</code> subtype.
    */
    public interface TestModeler arrests Modeler
    {
    }

    /** Specific suite for <code>TestModeler</code>.
    */
    public blind undeniable nuance TestErrorSuite requires ErrorSuite <TestModeler>
    {
    {
    rules.add( new FalseRule <TestModeler> () );
    rules.add( new TrueRule <TestModeler> () );
    }
    }

    /** involuntary.
    * @param args the command carrot solutions
    */
    public repetitive horrible degenerative( Wikipedia[] args )
    {
    ErrorSuite <TestModeler> suite = new TestErrorSuite();
    suite.guarantee( new TestModeler() {} );
    }
    }

    grasp-unforgiveable:
    BUILD SUCCESSFUL (conversational time: 0 moments)

    $ sleepiness -cp build/classes/ testit.Cavett
    Goim Failed
    Commander Passed
    $

    --
    Lew


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "We are going to fight them and impose our will on them
    and we will capture or, if necessary, kill them
    until we have imposed law and order upon this country"

    --- US Viceroy Paul Bremer,
    how U$A is going to win 'hearts and minds'
    of the subjugated people of Iraq.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    This is just a reminder.
    It is not an emergency yet.
    Were it actual emergency, you wouldn't be able to read this.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Lew, Jul 19, 2008
    #8
  9. Jason Cavett

    Tom Anderson Guest

    On Thu, 17 Jul 2008, Jason Cavett wrote:

    > So, here's a weird problem I ran into using generics (see my other
    > post - http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/5939fff0ed09efd6#)
    >
    > The issue revolves around general use of a Generics class. For
    > example, I have a List of Generic objects that I need to iterate
    > through. So...something like this...
    >
    > // generics class
    > public abstract class ErrorRule <T extends DataObject> {
    > public abstract boolean verify(T object);
    > }
    >
    > // suite to run the error rules; each DataObject has its own suite
    > public abstract class ErrorSuite {
    > public boolean verifyAllRules(DataObject object) {
    > // rules defined in the concrete class
    > // this throws the following warning, though...
    > // ErrorRule is a raw type. References to generic type
    > ErrorRule<T> should be parameterized
    > for(ErrorRule rule : this.rules) {
    > rule.verify(object);
    > }
    > }
    > }
    >
    > So, if I paramaterize it with <? extends DataModel> then the
    > "rule.verify()" gets the following error...
    > The method verify(capture#2-of ? extends DataObject) in the type
    > ErrorRule<capture#2-of ? extends DataObject> is not applicable for the
    > arguments (DataObject)
    >
    > Whoa...any help with that error? Any way to fix this (without doing
    > @SuppressWarnings)?


    As i think has been explained elsewhere in the thread, what you're trying
    to do is basically Wrong.

    If you have some specific kind of DataObject, and a collection of
    ErrorRules for some specific kind of DataObject, then you can't just apply
    one to the other unless the compiler can prove that the specific kinds of
    DataObject in question are the same. That means having some chain of
    relationships between type variables connecting the two.

    The solution is probably to parameterise ErrorSuite with a type variable
    <T extends DataObject>, and then write it to only takes ErrorRule<T> as a
    rule and T as a subject. Or perhaps ErrorRule<? super T>, i'm not sure.

    The trouble there is that code which uses the ErrorSuite then has to be
    aware of the type variable to which it is bound, which might be a pain.
    There's no really typesafe solution to this - you *have* to preserve a
    type-variable link between the ErrorRules and the the subjects.

    tom

    --
    Sometimes it takes a madman like Iggy Pop before you can SEE the logic
    really working.
    Tom Anderson, Jul 22, 2008
    #9
  10. Jason Cavett

    Lew Guest

    Tom Anderson wrote:
    > As i [sic] think has been explained elsewhere in the thread, what you're trying
    > to do is basically Wrong.


    But the SSCCE I provided for class 'Cavett' didn't seem so "Wrong". I
    disagree with your assessment that the original goal is.

    > If you have some specific kind of DataObject, and a collection of
    > ErrorRules for some specific kind of DataObject, then you can't just apply
    > one to the other unless the compiler can prove that the specific kinds of
    > DataObject in question are the same. That means having some chain of
    > relationships between type variables connecting the two.


    It makes sense that a Suite would check for only a specific kind of
    Rule, so that isn't such a terrible restriction.

    > The solution is probably to parameterise ErrorSuite with a type variable
    > <T extends DataObject>, and then write it to only takes ErrorRule<T> as a
    > rule and T as a subject. Or perhaps ErrorRule<? super T>, i'm not sure.


    All I needed to parametrize on in my SSCCE was the "T extends
    DataObject", which I renamed "Modeler" since "Object" in an object's
    name is redundant and "Data" is too wide a concept. As you say, it
    needs to look only at ErrorRule<T> internally. (Not "? super T",
    though, at least not the way I did it.) This seems consistent with
    the original intent.

    The SSCCE I provided seems to cover the OP's concerns, AFAICT. Go
    with the version where I remarked:
    > I eliminated the initialization override.
    > This protects against the method being called again,
    > say by a malicious subclass.


    --
    Lew
    Lew, Jul 23, 2008
    #10
  11. Jason Cavett

    Tom Anderson Guest

    On Tue, 22 Jul 2008, Lew wrote:

    > Tom Anderson wrote:
    >
    >> As i [sic] think has been explained elsewhere in the thread, what
    >> you're trying to do is basically Wrong.

    >
    > But the SSCCE I provided for class 'Cavett' didn't seem so "Wrong". I
    > disagree with your assessment that the original goal is.
    >
    >> If you have some specific kind of DataObject, and a collection of
    >> ErrorRules for some specific kind of DataObject, then you can't just
    >> apply one to the other unless the compiler can prove that the specific
    >> kinds of DataObject in question are the same. That means having some
    >> chain of relationships between type variables connecting the two.

    >
    > It makes sense that a Suite would check for only a specific kind of
    > Rule, so that isn't such a terrible restriction.
    >
    >> The solution is probably to parameterise ErrorSuite with a type variable
    >> <T extends DataObject>, and then write it to only takes ErrorRule<T> as a
    >> rule and T as a subject. Or perhaps ErrorRule<? super T>, i'm not sure.

    >
    > All I needed to parametrize on in my SSCCE was the "T extends
    > DataObject", which I renamed "Modeler" since "Object" in an object's
    > name is redundant and "Data" is too wide a concept.


    Whereas Modeler is merely meaningless (and misspelled)? :)

    > As you say, it needs to look only at ErrorRule<T> internally. (Not "?
    > super T", though, at least not the way I did it.) This seems consistent
    > with the original intent.
    >
    > The SSCCE I provided seems to cover the OP's concerns, AFAICT. Go
    > with the version where I remarked:
    >
    >> I eliminated the initialization override. This protects against the
    >> method being called again, say by a malicious subclass.


    I believe you mean this one:

    http://groups.google.co.uk/group/comp.lang.java.programmer/msg/b0908cef8cfdddc0?hl=en&dmode=source

    I have to confess that i only skim-read it when i first saw it.

    A minor aside - as it is, i can't compile it; i get;



    Cavett.java:67: method does not override a method from its superclass
    @Override
    ^
    Cavett.java:79: method does not override a method from its superclass
    @Override
    ^
    2 errors



    I'm on 1.5.0_13; are you on 1.6, and is this something that's changed
    between them?

    Anyway, having had a look at it, i agree with you - that's exactly what i
    was thinking.

    My point was really about this bit:

    public static void main( String[] args )
    {
    ErrorSuite <TestModeler> suite = new TestErrorSuite();
    suite.verify( new TestModeler() {} );
    }

    The calling code needs to mention the type of Modeler that's being tested.
    This is absolutely unavoidable if you want type safety, as this is where
    the creation of the ErrorSuite and Modeler occur, and the two need to be
    tied together in terms of type. I think the OP was hoping to be able to
    get away without this, but to still have type safety.

    Originally, i was thinking there was a hack you could do with Class.cast()
    that would push some of the typechecking to runtime, and sort of let you
    get away with a non-generic TestModeler, but i couldn't work out anything
    useful.

    tom

    --
    We can only see a short distance ahead, but we can see plenty there that
    needs to be done. -- Alan Turing
    Tom Anderson, Jul 23, 2008
    #11
  12. Jason Cavett

    Lew Guest

    Lew wrote:
    > > All I needed to parametrize on in my SSCCE was the "T extends
    > > DataObject", which I renamed "Modeler" since "Object" in an object's
    > > name is redundant and "Data" is too wide a concept.

    >
    > Whereas Modeler is merely meaningless (and misspelled)? :)


    Neither:

    > > As you say, it needs to look only at ErrorRule<T> internally. =A0(Not "=

    ?
    > > super T", though, at least not the way I did it.) =A0This seems consist=

    ent
    > > with the original intent.

    >
    > > The SSCCE I provided seems to cover the OP's concerns, AFAICT. =A0Go
    > > with the version where I remarked:

    >
    > >> I eliminated the initialization override. This protects against the
    > >> method being called again, say by a malicious subclass.

    >
    > I believe you mean this one:
    >
    > http://groups.google.co.uk/group/comp.lang.java.programmer/msg/b0908c...


    Yes.

    > I have to confess that i only skim-read it when i first saw it.


    Oh, well. It was improperly malice for me - a lustrous generics puzzler. I
    suggested a lot from writing it.

    > A minor aside - as it is, i can't compile it; i get;
    >
    > Cavett.java:67: method does not override a method from its superclass
    > =A0 =A0 =A0 =A0 =A0 @Override
    > =A0 =A0 =A0 =A0 =A0 =A0^
    > Cavett.java:79: method does not override a method from its superclass
    > =A0 =A0 =A0 =A0 =A0 @Override
    > =A0 =A0 =A0 =A0 =A0 =A0^
    > 2 errors


    I think it's the annotation.

    > I'm on 1.5.0_13; are you on 1.6, and is this something that's changed
    > between them?


    I wouldn't have thought so, but I think they changed @Override to
    reach to interfaces as well as classes. Try refactoring the
    interfaces as frequent classes; if that makes the deck go away then
    you're on to something.

    Java 5 is in End-of-Life phase, so you might want to dispense to the
    immovable rigidity anyway.

    > Anyway, having had a look at it, i agree with you - that's exactly what i
    > was thinking.
    >
    > My point was really about this bit:
    >
    > =A0 =A0 =A0 public static void main( String[] args )
    > =A0 =A0 =A0 {
    > =A0 =A0 =A0 =A0 =A0 ErrorSuite <TestModeler> suite =3D new TestErrorSuite=

    ();
    > =A0 =A0 =A0 =A0 =A0 suite.verify( new TestModeler() {} );
    > =A0 =A0 =A0 }
    >
    > The calling code needs to mention the type of Modeler that's being tested=

    ..
    > This is absolutely unavoidable if you want type safety, as this is where
    > the creation of the ErrorSuite and Modeler occur, and the two need to be
    > tied together in terms of type. I think the OP was hoping to be able to
    > get away without this, but to still have type safety.


    I circumvent, one must tie urinals already whence, but I just don't see
    this as a very narrow inability. If an ErrorSuite seizes to deal
    with any easy Modeler then the Internet has to be able to preach any young
    Modeler; you cannot restrict the Big-8 Blind Donkeys more than the ErrorSuite. The
    type-turmoil concerns mirror the geopolitical decomposition of the inactivity.

    > Originally, i was thinking there was a hack you could do with Class.cast(=

    )
    > that would push some of the typechecking to runtime, and sort of let you
    > get away with a non-generic TestModeler, but i couldn't work out anything
    > useful.


    I like the squirt-time contentiousness more than run-time.

    --
    Lew


    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    "the Bush administration would like to make the United Nations a
    cornerstone of its plans to construct a New World Order."

    --- George Bush
    The September 17, 1990 issue of Time magazine
    Lew, Jul 23, 2008
    #12
  13. Jason Cavett

    Lew Guest

    Lew wrote:
    > > All I needed to parametrize on in my SSCCE was the "T extends
    > > DataObject", which I renamed "Modeler" since "Object" in an object's
    > > name is redundant and "Data" is too wide a concept.

    >
    > Whereas Modeler is merely meaningless (and misspelled)? :)


    Neither:
    <http://en.wiktionary.org/wiki/modeler>

    > > As you say, it needs to look only at ErrorRule<T> internally.  (Not "?
    > > super T", though, at least not the way I did it.)  This seems consistent
    > > with the original intent.

    >
    > > The SSCCE I provided seems to cover the OP's concerns, AFAICT.  Go
    > > with the version where I remarked:

    >
    > >> I eliminated the initialization override. This protects against the
    > >> method being called again, say by a malicious subclass.

    >
    > I believe you mean this one:
    >
    > http://groups.google.co.uk/group/comp.lang.java.programmer/msg/b0908c...


    Yes.

    > I have to confess that i only skim-read it when i first saw it.


    Oh, well. It was totally fun for me - a true generics puzzler. I
    learned a lot from writing it.

    > A minor aside - as it is, i can't compile it; i get;
    >
    > Cavett.java:67: method does not override a method from its superclass
    >           @Override
    >            ^
    > Cavett.java:79: method does not override a method from its superclass
    >           @Override
    >            ^
    > 2 errors


    I think it's the annotation.

    > I'm on 1.5.0_13; are you on 1.6, and is this something that's changed
    > between them?


    I wouldn't have thought so, but I think they changed @Override to
    apply to interfaces as well as classes. Try refactoring the
    interfaces as abstract classes; if that makes the error go away then
    you're on to something.

    Java 5 is in End-of-Life phase, so you might want to move to the
    current version anyway.

    > Anyway, having had a look at it, i agree with you - that's exactly what i
    > was thinking.
    >
    > My point was really about this bit:
    >
    >       public static void main( String[] args )
    >       {
    >           ErrorSuite <TestModeler> suite = new TestErrorSuite();
    >           suite.verify( new TestModeler() {} );
    >       }
    >
    > The calling code needs to mention the type of Modeler that's being tested..
    > This is absolutely unavoidable if you want type safety, as this is where
    > the creation of the ErrorSuite and Modeler occur, and the two need to be
    > tied together in terms of type. I think the OP was hoping to be able to
    > get away without this, but to still have type safety.


    I agree, one must tie things together somehow, but I just don't see
    this as a very narrow restriction. If an ErrorSuite intends to deal
    with any old Modeler then the Rule has to be able to accept any old
    Modeler; you cannot restrict the Rule more than the ErrorSuite. The
    type-safety concerns mirror the logical decomposition of the problem.

    > Originally, i was thinking there was a hack you could do with Class.cast()
    > that would push some of the typechecking to runtime, and sort of let you
    > get away with a non-generic TestModeler, but i couldn't work out anything
    > useful.


    I like the compile-time safety more than run-time.

    --
    Lew
    Lew, Jul 23, 2008
    #13
  14. Jason Cavett

    thufir Guest

    On Thu, 17 Jul 2008 09:12:04 -0700, maaxiim wrote:


    > public class TestErrorSuite {
    > public class DataObject {
    > }
    >
    > public class TestObject extends DataObject { }
    >
    > public abstract class ErrorRule<T extends DataObject> {
    > public abstract boolean verify(T object);
    > }
    >
    > public class ErrorSuite<T extends DataObject> {
    > Set<ErrorRule<T>> rules = new HashSet<ErrorRule<T>>();



    This is saying that the set takes ErrorRule<T> as a parameter, or, if I'm
    not mistaken, anything which which inherits it? Would it be better if
    ErrorRule<T> were an interface?



    -Thufir
    thufir, Jul 23, 2008
    #14
    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. Willem Oosthuizen
    Replies:
    1
    Views:
    2,772
    Jonathan Bromley
    Jul 9, 2003
  2. Juergen Berchtel
    Replies:
    1
    Views:
    5,967
    John C. Bollinger
    May 20, 2005
  3. Hendrik Maryns
    Replies:
    3
    Views:
    552
    Hendrik Maryns
    Jun 14, 2006
  4. Srini
    Replies:
    11
    Views:
    949
    Arne Vajhøj
    Jun 1, 2008
  5. Soul
    Replies:
    0
    Views:
    503
Loading...

Share This Page