Generics Issue

J

Jason Cavett

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
 
L

Lew

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.
 
J

Joshua Cranmer

Jason said:
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.
 
M

maaxiim

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...
 
J

Jason Cavett

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...

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());
}

}
 
M

maaxiim

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...
 
L

Lew

Chris said:
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."
 
L

Lew

....
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.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
T

Tom Anderson

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
 
L

Lew

Tom said:
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:
 
T

Tom Anderson

Tom said:
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 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
 
L

Lew

Lew said:
Whereas Modeler is merely meaningless (and misspelled)? :)
Neither:



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
 
L

Lew

Lew said:
Whereas Modeler is merely meaningless (and misspelled)? :)
Neither:



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.
 
T

thufir

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

generics puzzle 57
Hairy generics question 29
Generics and Polymorphism 5
Generics ? 14
Tree design with generics 2
Generics 24
can this be done with generics? 32
Problem with generics and dynamic array copy 7

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top