【发布时间】:2013-12-29 20:46:11
【问题描述】:
我必须将我的代码更改为从使用反射到生成随机参数的解决方案。
我不知道如何实现这个...
这是类生成器:
public class SweetsGenerator implements Generator<Sweets>, Iterable<Sweets> {
private static final Logger LOG = Logger.getLogger(SweetsGenerator.class);
@SuppressWarnings("rawtypes")
private Class[] types = {
WhiteChocolate.class, MilkChokolate.class, DarkChocolate.class,
DesertChocolate.class, PorousChocolate.class,
};
private static Random rand = new Random();
public SweetsGenerator() {
}
private int size = 0;
public SweetsGenerator(int sz) {
size = sz;
}
public Sweets next() {
try {
return (Sweets) types[rand.nextInt(types.length)].newInstance();
} catch (Exception e) {
LOG.error("RuntimeException", e);
throw new RuntimeException(e);
}
}
class SweetsIterator implements Iterator<Sweets> {
int count = size;
public boolean hasNext() {
return count > 0;
}
public Sweets next() {
count--;
return SweetsGenerator.this.next();
}
public void remove() { // Not implemented
LOG.error("UnsupportedOperationException");
throw new UnsupportedOperationException();
}
};
public Iterator<Sweets> iterator() {
return new SweetsIterator();
}
}
如何规避这种方法并创建新的类元素,例如:
新白巧克力((rand.nextDouble() * 100) + 1, (rand.nextDouble() * 200) + 1);
我不能将它与我们可以创建的随机生成类女巫元素结合起来。
这是Sweets抽象类的内容和其中一个实现:
public abstract class Sweets {
private double sugarLevel;
private double weight;
public double getSugarLevel() {
return sugarLevel;
}
public double getWeight() {
return weight;
}
public void setSugarLevel(double sugarLevel) {
this.sugarLevel = sugarLevel;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName() + " " + sugarLevel + " " + weight);
return sb.toString();
}
}
public class Chocolate extends Sweets {
public Chocolate() {
}
public Chocolate(double aSugarLevel, double aWeight) {
setSugarLevel(aSugarLevel);
setWeight(aWeight);
}
}
更新:
我尝试通过 skiwi 的建议修改 next()。
下一个更改版本:
public Sweets next() {
Sweets current = instances[rand.nextInt(instances.length)];
Double param1 = (rand.nextDouble() * 100) + 1;
Double param2 = (rand.nextDouble() * 200) + 1;
System.out.println("parameters: " + Math.round(param1) + " " + Math.round(param2));
try {
return (Sweets) current.getClass()
.getConstructor(Double.class, Double.class)
.newInstance(Math.round(param1), Math.round(param2));
// Report programmer errors at run time:
} catch (Exception e) {
LOG.error("RuntimeException", e);
throw new RuntimeException(e);
}
}
但它会引发下一堆异常:
23:25:51,337 ERROR main SweetsGenerator:next:52 - RuntimeException
java.lang.NoSuchMethodException: com.epam.lab.chocolate.DarkChocolate.<init>(java.lang.Double, java.lang.Double)
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getConstructor(Class.java:1708)
at com.epam.lab.SweetsGenerator.next(SweetsGenerator.java:48)
at com.epam.lab.NewYearGift.generate(NewYearGift.java:37)
at com.epam.lab.GiftList.generateGift(GiftList.java:47)
at com.epam.lab.GiftList.main(GiftList.java:59)
Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodException: com.epam.lab.chocolate.DarkChocolate.<init>(java.lang.Double, java.lang.Double)
at com.epam.lab.SweetsGenerator.next(SweetsGenerator.java:53)
at com.epam.lab.NewYearGift.generate(NewYearGift.java:37)
at com.epam.lab.GiftList.generateGift(GiftList.java:47)
at com.epam.lab.GiftList.main(GiftList.java:59)
Caused by: java.lang.NoSuchMethodException: com.epam.lab.chocolate.DarkChocolate.<init>(java.lang.Double, java.lang.Double)
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getConstructor(Class.java:1708)
at com.epam.lab.SweetsGenerator.next(SweetsGenerator.java:48)
... 3 more
这个问题的解决方法是改一行:
return (Sweets) current.getClass().getConstructor(double.class, double.class) .newInstance(Math.round(param1), Math.round(param2));
如何保护这个生成器的逻辑并随机创建带参数的元素?
有什么建议吗?
【问题讨论】: