防止使用编译器技巧进行方法调用

| 我大致有以下几种类型:
interface Record {}
interface UpdatableRecord extends Record {}

interface Insert<R extends Record> {

    // Calling this method only makes sense if <R extends UpdatableRecord>
    void onDuplicateKeyUpdate();
}
我想在致电
onDuplicateKeyUpdate()
时对
<R>
有更多限制。原因是,仅当
<R>
绑定到
UpdatableRecord
的任何子类型,而不仅仅是ѭ5this时,此方法才有意义。例子:
Insert<?>               i1;
Insert<Record>          i2;
Insert<UpdatableRecord> i3;

// these shouldn\'t compile
i1.onDuplicateKeyUpdate();
i2.onDuplicateKeyUpdate();

// this should compile
i3.onDuplicateKeyUpdate();
是否有任何技巧或方法可用于仅针对一个方法声明为类的泛型类型添加附加限制? 注意: 声明“ 7”不是一个选择,因为我希望为不可更新的记录设置一个“ 8”的灵活性 派生ѭ9并向下推该方法可能有一个选择,但我真的不想引入一种新类型。我有几种方法,但有几种不同的限制,这会导致类型爆炸。 投掷ѭ10很明显,但似乎Java 1.4做到了。我真的很想知道我是否可以使用泛型和编译器来解决此问题。 理想的解决方案:
// This would be an annotation to be interpreted by the compiler. There is no such
// thing in Java, as far as I know. But maybe there\'s a trick having the same effect?
@Require(R extends UpdatableRecord)
void onDuplicateKeyUpdate();
    
已邀请:
如果要在接口中定义它,则必须在希望实现该接口的任何类中实现它。因此,您无法在实现
Insert<R extends Record>
接口的任何类中实现
onDuplicateKeyUpdate
。 您已经在接口中指定了“ 14”,因此这成为了合同的一部分,这意味着可以使用任何“ 5”子类型。我想不出一种使用泛型添加其他约束的方法,该约束将其限制为仅
UpdatableRecord
类型。 另外,您不能根据
R
的类型在界面中做出决定,因为该信息会由于类型擦除而消失。 在我看来,您的问题与
Record
UpdatableRecord
之间的差异有关。由于接口是一般性合同,因此我认为接口中不应包含特定于类型的行为。因此,您将不得不找出另一种方式来解决差异。我的解决方案是在
Record
接口中实现一种方法(返回
boolean
),该接口称为
canUpdate
,您可以在
onDuplicateKeyUpdate
中使用。这样,如果记录不支持该操作或不执行任何操作(如果您想避免异常,并且在您的业务逻辑上下文中不执行任何操作),则可以抛出“ 10”。 这不在我的头上。可能会有更好的解决方案。我会再考虑一下。 编辑 我再考虑了一下,正是您的最新编辑使我对此有所考虑。
<R extends Record>
适用于整个班级。因此,无法在特定方法的上下文中覆盖或缩小它。像您提到的那样的注释需要在编译器级别实现,在该级别,我什至不确定是否可以访问R类型(由于类型擦除)。因此,您要说的可能是不可能的。 从概念上讲,IMO不可能满足您的要求,因为您在合同中指定了合同例外。听起来还好像实现细节正在您的界面中蔓延,因为这些界面不应该试图弄清楚什么可以做或不能做。应该在具体实施中确定。     
当您创建
Insert
时,Vivin很好地说明了您所订立的合同。我想问一问“ 2”在这种情况下是否真的有意义。它似乎仅对
Record
的一个子类型特定。 如果您可以将该功能转换为另一种“ 26”方法(例如“ 30”?),则可以在那里测试对象的类型并采取相应的措施。例如,
[pseudo-code]
method execute( R record )
 try
  insertRecord( record )
 catch ( KeyAlreadyExistsException e )
  if ( record instanceof UpdatableRecord )
   updateRecord( record )
  end if
 end try
end method
如果您正在寻找一种更面向对象的方法,则可以将逻辑插入到
Record
子类中。在那里,我将
Insert
更改为
Insertable
,给它一个
insert()
方法,并让
Record
实现
Insertable
。这样,
Record
的每个子类都可以知道to35ѭ自身的正确方法。我不确定是否适合您的设计策略...     

要回复问题请先登录注册