如何从Java中的通配符类推断相关的类型变量?
我需要从带有两个类型参数的库中调用generic如何从Java中的通配符类推断相关的类型变量?,java,scala,generics,groovy,type-inference,Java,Scala,Generics,Groovy,Type Inference,我需要从带有两个类型参数的库中调用genericf函数,如下所示: public <D extends Data<K> & Property<P>, K extends Key<D>, P extends Object> void f(Class<D> classD, K key) { ... } 现在,我的程序需要调用f函数,但是,我有: Class<?> cla
f
函数,如下所示:
public <D extends Data<K> & Property<P>, K extends Key<D>, P extends Object>
void f(Class<D> classD, K key) {
...
}
现在,我的程序需要调用f
函数,但是,我有:
Class<?> clazz = ...;
Object key = ...;
// I know clazz and key can satisfy the constraints
// but cannot see the exact class.
f(clazz, key);
// This is what I want to invoke but this statement alone
// will lead to compile time failures.
Class clazz=。。。;
对象键=。。。;
//我知道clazz和key可以满足约束条件
//但看不到确切的类别。
f(clazz,key);
//这是我想调用的,但仅此语句
//将导致编译时失败。
我可以创建一些满足需求的本地接口,并将两个参数转换为它们,如下所示。它可以通过编译器,但会导致强制转换错误
public interface MyData<P> extends Property<P>, Data<MyKey<P>> {
}
public interface MyKey<P> extends Key<MyData<P>> {
}
公共接口MyData扩展属性
,数据{
}
公共接口MyKey
扩展密钥{
}
因此,我的问题是,是否有可能从Java(或Groovy/Scala)中的通配符推断出正确的类型D
和K
谢谢你的帮助 没有任何方法可以从
Class
或K
从Object
推断Class
。泛型通配符和对象类型实际上意味着编译器没有关于这些变量类型的任何附加信息
当然,当您尝试将对象
强制转换为MyKey
时,如果它不是一个对象,您将得到ClassCastExceptions
但是如果您知道clazz
是一个类
,key
是一个MyBar
,给定一个扩展Data
的MyFoo
和一个扩展key
的MyBar
,您可以添加一些强制转换:
f((类)clazz,(MyBar)对象);
编译器将警告您类型安全,但这是传递类和对象的代价。A类不覆盖有界类型
,而对象也不能覆盖有界K扩展键。您可以在方法签名中指定这些类型(因为您不能在变量中声明它们):
公共类类型{
公开的
空f(D类,K键){
}
公共静电
void main(字符串[]args){
类型t=新类型();
类klazz=null;
K key=null;
t、 f(克拉兹,钥匙);
}
}
接口数据{}
接口属性{}
接口键{}
在groovy中,您可以动态删除以下类型:
class Types {
def f(Class<?> classD, key) {
"foobar"
}
static main(args) {
def t = new Types()
Class<?> klazz = null
Object key = null
assert t.f(klazz, key) == "foobar"
}
}
interface Data<T> {}
interface Property<T> {}
interface Key<T> {}
类类型{
def f(D类,钥匙){
“foobar”
}
静态干管(args){
def t=新类型()
类klazz=null
对象键=空
断言t.f(klazz,key)=“foobar”
}
}
接口数据{}
接口属性{}
接口键{}
public class Types {
public
<D extends Data<K> & Property<P>, K extends Key<D>, P extends Object>
void f(Class<D> classD, K key) {
}
public static
<D extends Data<K> & Property<P>, K extends Key<D>, P extends Object>
void main(String[] args) {
Types t = new Types();
Class<D> klazz = null;
K key = null;
t.f(klazz, key);
}
}
interface Data<T> {}
interface Property<T> {}
interface Key<T> {}
class Types {
def f(Class<?> classD, key) {
"foobar"
}
static main(args) {
def t = new Types()
Class<?> klazz = null
Object key = null
assert t.f(klazz, key) == "foobar"
}
}
interface Data<T> {}
interface Property<T> {}
interface Key<T> {}