使用ValueSelector防止某些移动会导致ClassCastException



我有一个Lecture类,startTime规划变量和固定持续时间。我试图过滤掉导致结束时间超过16:00的移动。

我已经写了一个选择过滤器:
public class LectureOutOfBoundsSelectionFilter
implements SelectionFilter<Schedule, Lecture> {
@Override
public boolean accept(ScoreDirector<Schedule> sd, Lecture lecture) {
return !lecture.isOutOfBounds();
}
}

我配置如下

<changeMoveSelector>
<filterClass>package.PinnedTimeslotChangeMoveFilter</filterClass>
<valueSelector>
<filterClass>packager.LectureOutOfBoundsSelectionFilter</filterClass>
</valueSelector>
</changeMoveSelector>

但是我在Lecture中得到一个与不同规划变量相关的类强制转换异常。我试过添加variableName="startTime",但这会触发不同的类强制转换异常。

我是否在正确的轨道上,variableName属性实际上是如何工作的?

我将从您的附加注释开始,您将进一步解释:

variableName="startTime"我得到java.lang.ClassCastException: class package.ImmutableTimeslot cannot be cast to class package.Lecture。没有variableName设置,我得到java.lang.ClassCastException: class package.Room cannot be cast to class package.Lecture

对于这种行为有一个解释,尽管它不是很直观:

  • 当您将过滤器放在没有变量名的值选择器上时,两个变量类型都将到达过滤器。在本例中,ImmutableTimeslotRoom。因为你的过滤器期望一个Lecture,两者中的一个都会抛出异常。
  • 当你指定选择器的变量名为startTime时,这将不再触发room变量值的值选择器;因此,你得到一个异常,ImmutableTimeslot不匹配Lecture

在这两种情况下,问题似乎是您的过滤器期望Lecture实例(实体),但求解器正在发送ImmutableTimeslotRoom(规划变量的值)。这可以说是选择器的正确行为(强调"value"这个词)。

我称它为"不太直观"的原因分为两部分:

  • 始终需要相同的SelectionFilter接口,无论应用于移动选择器,实体选择器还是值选择器。因此,根据您打算使用它的地方,所需的泛型类型是不同的,这令人困惑。(一个移动,一个实体或一个值)
  • 在有多个变量的情况下(比如你的),没有在选择器上指定variableName,通用参数需要是Object,因为过滤器将接收两种类型的值,这是避免异常的唯一方法。

总而言之,不是最好的设计;它从2012年开始,由于保持向后兼容性和我们实际上不鼓励使用选择过滤器,它一直保存到今天没有改变。

相关内容

  • 没有找到相关文章

最新更新