From: Jason Cavett on
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
From: Lew on
On Jul 17, 11:08 am, Jason Cavett <jason.cav...(a)gmail.com> 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
From: Joshua Cranmer on
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
From: maaxiim on
On Jul 17, 11:49 am, Joshua Cranmer <Pidgeo...(a)verizon.invalid> 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(a)de6ced returns true
rule: test.TestErrorSuite$1(a)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
From: Jason Cavett on
On Jul 17, 12:12 pm, maaxiim <maax...(a)gmail.com> wrote:
> On Jul 17, 11:49 am, Joshua Cranmer <Pidgeo...(a)verizon.invalid> 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(a)de6ced returns true
> rule: test.TestErrorSuite$1(a)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());
}

}