在Java中是否可以禁止泛型中的某些超类?
我想问一下,在Java 8+中是否可以声明一个泛型绑定在Java中是否可以禁止泛型中的某些超类?,java,generics,Java,Generics,我想问一下,在Java 8+中是否可以声明一个泛型绑定T,以便它扩展超类/超接口U(可以是Object,或者Serializable),但如果T扩展L(必须首先扩展U),则会中断编译 我在使用filter range对象时发现了这个问题:我的一个开发人员调用了错误的方法,并且花了很多时间询问为什么它会给出不一致的结果。所以我想帮助她以某种方式更改方法签名,以便尽早发现她使用了错误的代码 我将以一种非常简单的方式显示我的示例案例。我们正在讨论表和动态过滤器 #Displays a text "[f
T
,以便它扩展超类/超接口U
(可以是Object
,或者Serializable
),但如果T
扩展L
(必须首先扩展U
),则会中断编译
我在使用filter range对象时发现了这个问题:我的一个开发人员调用了错误的方法,并且花了很多时间询问为什么它会给出不一致的结果。所以我想帮助她以某种方式更改方法签名,以便尽早发现她使用了错误的代码
我将以一种非常简单的方式显示我的示例案例。我们正在讨论表和动态过滤器
#Displays a text "[field name] is equal to [value]"
#Value (T) must be Oject
#Internally uses Object::toString
#Null shows blank string
public static String <T> localizeEq(Localizable fieldName, T value);
<LocalDate> localize(forI18nLabel("DATE_OF_BIRTH_LABEL",dateOfBirth)
"Date of birth equals 01/01/1900" (en)
"syntymäaika on 01/01/1990" (fi)
#Additional diplays for "ge, gte, le..."
#Overload methods not displayed
#SimpleFilter is {op:"ge|ge|eq...",value:""}}
#The effective display depends on the op attribute
#Example "[field name] is [operator] [value]"
#Example "[field name] is less or equal than [upper]"
#If <filter != null but filter.op == null || filter.value> the method returns null
public static String <T> localize(Localizable fieldName, SimpleFilter<T> filter)
#localize(forI18nLabel("SALARY"),salaryFilter)
#salaryFilter = {op:"lt",value:10000}
#Salary is less than 10000 (en)
[编辑3]
密码打开了。请注意,在存储库代码中,我们静态导入SimpleFilter.filter
或LocalDateRangeFilter.filter
方法。在这个问题中,假设localize(Localizable,SimpleFilter)
与其他方法属于同一类。请注意,在我们的存储库中还有其他几个*RangeFilter类支持Joda Time、Java Util Date和NumericRange。他们都面临同样的问题
无论如何,我想把重点放在问题的范围上:禁止泛型扩展,这在JLS中似乎是不可能的
我想问一下,在Java8+中是否可以声明泛型
绑定T
,以便扩展超类/超接口U
(可以是
Object
,或Serializable
),但如果T
扩展L
(其中
必须先扩展U
)
伪代码中的T
似乎是一个类型参数,而不是一个边界。界限是不同的,事实上,在T
上加一个界限似乎就是你要问的。事实上,如果没有一个(特别是没有下限),您的localizeEq()
方法将无法从泛型中获得任何好处。目前来看,如果您完全去掉T
,并声明第二个参数的类型为Object
(相当于当前代码)或可序列化
或其他类型,则该方法会更清晰
我认为该方法是泛型的,希望以某种方式使用其类型参数来排除某些子类型的参数,但这在Java中是不可能的,因为
- 类型下限是包含的,而不是独占的
- 类型下限将满足绑定的类型限制为一行继承,这似乎与您的意图不一致
Serializable
和开发人员无意中调用了localizeq
,这
接受原子值,参数类型为SimpleFilter
扩展可序列化的
。方法localizeq
构建一个过滤文本
“[字段名]等于{op:null,value:null}”
如果不应该将SimpleFilter
传递给localizedEq()
方法,那么我认为这里存在设计缺陷。当然,您可以在运行时捕获冲突,但是类型系统没有提供一种方式来表示您正在寻找的编译时约束
对于我的具体情况,还有一个技巧,但它涉及到创建十几个重载的不推荐方法:
@Deprecated
public static String localize[Eq|Ne...](Localizable fieldName, SimpleFilter<?> value){ throw new UnsupportedOperationException("Wrong method");}
事实上,重载可能是最好的解决方案,但我建议从另一个方向着手。与其为localizeEq
、localizeNe
等添加重载,不如弃用这些方法的现有版本,并使用一个或多个版本重载localize
,这些版本为非SimpleFilter
的参数提供所需的行为
我想问一下,在Java8+中是否可以声明泛型
绑定T
,以便扩展超类/超接口U
(可以是
Object
,或Serializable
),但如果T
扩展L
(其中
必须先扩展U
)
伪代码中的T
似乎是一个类型参数,而不是一个边界。界限是不同的,事实上,在T
上加一个界限似乎就是你要问的。事实上,如果没有一个(特别是没有下限),您的localizeEq()
方法将无法从泛型中获得任何好处。目前来看,如果您完全去掉T
,并声明第二个参数的类型为Object
(相当于当前代码)或可序列化
或其他类型,则该方法会更清晰
我认为该方法是泛型的,希望以某种方式使用其类型参数来排除某些子类型的参数,但这在Java中是不可能的,因为
- 类型下限是包含的,而不是独占的
- 类型下限将满足绑定的类型限制为一行继承,这似乎与您的意图不一致
Serializable
和开发人员无意中调用了localizeq
,这
接受原子值,参数类型为SimpleFilter
扩展可序列化的
。方法localizeq
构建一个过滤文本
“[字段名]等于{op:null,value:null}”
如果不应该将SimpleFilter
传递给localizedEq()
方法,那么我认为这里存在设计缺陷。当然,您可以在运行时捕获冲突,但是类型系统没有提供表示编译时约束的方法