简体   繁体   English

Java在泛型类型参数中使用关系

[英]Java using relation in generics type argument

Currently I have this setup: 目前我有这个设置:

public abstract class Manager<B extends Bean, C extends AbstractConstraint> { 
    public final int insert(B b);

    public final boolean update(B b);

    public final boolean delete(B b);

    public final B get(C... c);

    public final List<B> search(C... c);

    public final List<B> getAll();
}

public interface Bean { }

public abstract class AbstractConstraint { }

concretely used in: 具体用于:

public class AccountManager extends Manager<AccountBean, AccountConstraint> { }

public class AccountBean implements Bean { }

public class AccountConstraint extends AbstractConstraint { }

A few remarks: 几点评论:

  • Bean is the lowest entity possible. Bean是可能的最低实体。 This is the direct instance of a row from a table in the database. 这是数据库中表的行的直接实例。
  • A concrete implementation of AbstractConstraint should not implement/extend a concrete implementation of Bean , unless I am mistaken here. AbstractConstraint的具体实现不应该实现/扩展Bean的具体实现,除非我在这里弄错了。

Via the Manager I can be sure that all you can pass in is a concrete version of <Bean, AbstractConstraint> . 通过Manager我可以确定您传入的所有内容都是<Bean, AbstractConstraint>的具体版本。

However currently it is entirely valid to define this: 但是目前定义它是完全有效的:

public class BogusManager extends Manager<AccountBean, CharacterConstraint> { }

which makes no sense at all, how can I restrict the code such that this is not allowed anymore? 这根本没有意义,我怎么能限制代码使得不再允许这样做?

I think that I have two options: 我认为我有两个选择:

1) Change AccountConstraint to AccountConstraint<AccountBean> , but I do not think that it would be valid since the type argument would not be used in AccountConstraint itself. 1)更改AccountConstraintAccountConstraint<AccountBean>但我不认为这将是有效的,因为类型参数将不会在使用AccountConstraint本身。

2) Have a way to define a relation R and let Manager check if <B, C> is in relation R , in other words you would need to check R(B, C) . 2)有办法定义关系R并让Manager检查<B, C>是否与R ,换句话说,你需要检查R(B, C) But you would also need to be able to define a relation R<AccountBean, AccountConstraint> then, which would mean that R = Manager , but I don't think that it could be true. 但是你还需要能够定义一个关系R<AccountBean, AccountConstraint> ,这意味着R = Manager ,但我不认为它可能是真的。 Anyway, how would I be able to implement this if it would be true? 无论如何,如果这是真的,我怎么能够实现呢?

Regards. 问候。

Your first option is legal, you do not need to use type variable. 您的第一个选项是合法的,您不需要使用类型变量。

For the second option, you need to pass class instances of bean and constraint to manager constructor which will check if this is legal pair. 对于第二个选项,您需要将beanconstraint类实例传递给manager构造函数,该构造函数将检查这是否为合法对。 As far as I know there is no way to implement such check in source only, ie add declarative constraint to source code. 据我所知,没有办法只在源代码中实现这样的检查,即向源代码添加声明性约束。

Something like this should satisfy a compile-time version of option 2: 这样的东西应该满足选项2的编译时版本:

interface Witness< B, C > {}

public final class AccountConstraintsForAccountsOnly implements Witness< AccountBean, AccountConstraint > {}
public final class CharacterConstraintsForCharactersOnly implements Witness< CharacterBean, CharacterConstraint > {}

public abstract class Manager< B extends Bean, C extends AbstractConstraint, W extends Witness< B, C > { ... }

For Option 1 对于选项1

 //add a Type    
abstract class AbstractConstraint<T>{}
//Type is tied to your Concrete bean
abstract class Manager<B extends Bean, C extends AbstractConstraint<B> >
{
.
.
.
}

While implementing the Constraint , state what type of Constraint it is, by just passing the Bean Type 在实施的Constraint ,状态什么类型的Constraint被刚好路过的是, Bean

Ex. 防爆。

 class BogusBean implements Bean { }
 class BogusConstraint extends AbstractConstraint<BogusBean> { }
 class BogusManager extends Manager<BogusBean, BogusConstraint> {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM