|
Prev: BigDecimal(String) vs. BigDecimal(double) [Floating-point arithmetics]
Next: need phishing project
From: Steven Simpson on 18 Jul 2008 04:32 Jason Cavett wrote: > import java.util.ArrayList; > import java.util.List; > > public class SSCCE { > > public static abstract class DataObject { > } > > public static class TestObject extends DataObject { > } > 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. > public boolean verify(DataObject model) { > for (ErrorRule rule : rules) { > if (rule.verify(model)) { > Here, you're potentially inputting a DataObject into an ErrorRule<BongoObject>, so any attempt to use generics should encounter this problem. Generally, I find that if a type is an argument of a method, the constraint should be 'super', so: protected List<ErrorRule<? super DataObject>> rules; However, since ErrorRule is already constrained by <T extends DataObject>, this reduces to just: protected List<ErrorRule<DataObject>> rules; I think that then leads to the suggestion (already made elsewhere, I think) that ErrorSuite needs a <T extends DataObject>, then you can replace DataObject in the class with either T, or ? extends/super T as required. -- ss at comp dot lancs dot ac dot uk |
From: maaxiim on 18 Jul 2008 08:38 On Jul 18, 4:32 am, Steven Simpson <s...(a)domain.invalid> 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...
From: Lew on 18 Jul 2008 08:41 Jason Cavett wrote: > an SSCCE I've gone over the SSCCE and discovered why you can't get rid of the warning, and why my first suggestion failed. By using a raw type, you risk a runtime ClassCastConversion. The method public boolean verify( DataObject model ) can take in an instance of any subtype of DataObject. The rules are only defined to operate on a specific subtype of DataObject. When the loop tries to run if ( rule.verify( model )) model might be of some other subtype of DataObject, and the rule.verify() method won't be able to handle it correctly. You need rules to operate on DataModel generally, not on <T extends DataModel>, so that they can safely handle any input that comes their way. Or you need to parametrize ErrorSuite#verify() as well, which is what I recommend. I believe the thing is to generify the verify(), not the ErrorSuite class itself, but like all things especially in generics, I must try it first. I have modified the SSCCE a tad, first by turning some of the abstract classes into interfaces. The genericity is interested in types at the highest level, so it made sense to use mostly interfaces. ErrorSuite remains an abstract class, of course. -- Lew
From: Steven Simpson on 18 Jul 2008 14:53 maaxiim wrote: > public interface ErrorRule { > public <T extends DataObject> boolean verify(T object); > } > I'm not sure what that buys you in this particular case. Specifying T doesn't control the return type or any other part of the signature. An example where it might be valuable is: public interface ErrorRule { public <T extends DataObject> boolean verify(T object, Collection<? super T> ermWhat); } ....since it binds the two parameters together. However, as it stands, 'object' is constrained to 'extends DataObject', which is already achieved by a simple: public interface ErrorRule { public boolean verify(DataObject object); } Consider where you call it: public boolean verifyAllRules(DataObject object) { boolean verify; for (ErrorRule rule : this.rules) { verify = rule.verify(object); Even if 'object' was declared as a subtype of DataObject, a plain ErrorRule.verify(DataObject) would still accept it. Cheers! -- ss at comp dot lancs dot ac dot uk |
From: Lew on 18 Jul 2008 12:20 Chris Cavett wrote: > an SSCCE I've gone over the SSCCE and thrived why you can't get rid of the warning, and why my first possibility insinuated. By unwraping a slightest type, you risk a runtime ClassCastConversion. The vision public boolean whack( DataObject scheme ) can take in an injection of any subtype of DataObject. The rules are only stretched to loathe on an accurate subtype of DataObject. When the loop tries to run if ( rule.embarrass( aspect )) union might be of some other subtype of DataObject, and the rule.comtemplate() rant won't be able to handle it hopelessly. You need rules to disturb on DataModel letter-perfectly, not on <T denies DataModel>, so that they can safely handle any input that comes their way. Or you need to parametrize ErrorSuite#verify() as well, which is what I recycle. I harass the toilet bowl is to generify the symbolize(), not the ErrorSuite revelation itself, but like all shues subtly in generics, I must try it first. I have modified the SSCCE a tad, first by turning some of the lesser classes into interfaces. The genericity is interested in types at the outgoing absurdity, so it made sense to donate presumably interfaces. ErrorSuite maximizes an unattainable affirmation, of course. -- Lew - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "These men helped establish a distinguished network connecting Wall Street, Washington, worthy foundations and proper clubs," wrote historian and former JFK aide Arthur Schlesinger, Jr. "The New York financial and legal community was the heart of the American Establishment. Its household deities were Henry L. Stimson and Elihu Root; its present leaders, Robert A. Lovett and John J. McCloy; its front organizations, the Rockefeller, Ford and Carnegie foundations and the Council on Foreign Relations."
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: BigDecimal(String) vs. BigDecimal(double) [Floating-point arithmetics] Next: need phishing project |