Java字段类型是否为一般递归自我类型的值? [英] Java field type for a value of a generically recursive self-type?

查看:104
本文介绍了Java字段类型是否为一般递归自我类型的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个基类定义递归自我类型的类层次:

 抽象类A< T extends A< T>> {} 

如何声明另一个类(在T中不应该是通用的,因为这样的T



以下行不通:


$可以在对象的整个生命周期内变化) b $ b

  public class B {
//编译失败,因为捕获?不足够窄
私人A<>一个;

public< T extends A< T>> setA(T a){
this.a = a;




$ b

- 问题结束 -



我注意到一些StackOverflow成员倾向于用你为什么要这么做?来解决某些难题。以下是我使用此模式的理由 - 您可以注意到,Java标准库在Enum类的定义中也使用了递归自我类型: Enum< E extends Enum< E>> 。这个问题同样可以作为如何定义类型为 Enum <?>< / code>的字段来解答。



例如:

 抽象类A< T extends A< T>> {
public abtract T self();
public B< T> bify(Bifyer bifyer){
return bifyer.bify(self());
}
}



包含子类:

  class ASub1 extends A< ASub1> {
public ASub1 self(){return this;}
}

class ASub2 extends A< ASub2> {
public ASub2 self(){return this ;}
}

绑定到并行类层次结构:

 抽象类B< T extends A< T>> {
}

class BSub1< T extends A< T>>实现B< T> {}
class BSub2< T extends A< T>>实现B< T> {}
//和其他



和w第二代B实例由Bifyer接口的实现管理: bify(ASub1 asub1);
B< ASub2> bify(ASub2 asub2);
}

这个接口的实现可能为B返回一个BSub1或BSub2。这是本质上是Bifyer是访问者的Visitor模式的应用程序,但与标准Visitor不同,accept方法返回值而不是void。这提供了一个模块化框架,其中可以指定不同的Bifyer实现,以便为Bify方法提供替代行为和返回类型 - 比如为B的每个子类提供一个。 解决方案

如果通过 A 限制通配符,它应该可以工作:

  public class B {
private A <?延伸A>一个;

public< T extends A< T>> void setA(T a){
this.a = a;
}
}


Given a class hierarchy where the base class defines a recursive self-type:

abstract class A<T extends A<T>> { }

How can I declare another class (which should not be generic in T, because such a T could vary over the lifetime of the object) with a field that can hold any subclass of A?

The following does not work:

public class B {
    //fails to compile, because the capture of ? is not sufficiently narrow
    private A<?> a;

    public <T extends A<T>> setA(T a) {
        this.a = a;
    }
}

-- END OF QUESTION --

I've noticed a tendency of a number of StackOverflow members to approach certain difficult questions with "why are you doing that in the first place?" The following is a justification of my use of this pattern - you can note that the Java standard library also uses recursive self-types in its definition of the Enum class: Enum<E extends Enum<E>>. This question could similarly be asked as "how to define a field of type Enum<?>.

Justification example:

abstract class A<T extends A<T>> {
    public abtract T self();
    public B<T> bify(Bifyer bifyer) {
        return bifyer.bify(self());
    }
}

with subclasses:

class ASub1 extends A<ASub1> { 
    public ASub1 self() { return this; }
}       

class ASub2 extends A<ASub2> { 
    public ASub2 self() { return this; }
}       

bound to a parallel class hierarchy:

abstract class B<T extends A<T>> {
}

class BSub1<T extends A<T>> implements B<T> { }
class BSub2<T extends A<T>> implements B<T> { }
//and others

And with generation of B instances managed by implementations of a Bifyer interface:

interface Bifyer {
    B<ASub1> bify(ASub1 asub1);
    B<ASub2> bify(ASub2 asub2);        
}

Implementations of this interface may return a BSub1 or BSub2 for the B. This is essentially an application of the Visitor pattern where the Bifyer is the visitor, but unlike the standard Visitor the accept method returns a value instead of void. This provides a modular framework where different Bifyer implementations can be specified to provide alternate behavior and return types for the Bify method - say one for each subclass of B.

解决方案

If you bound the wildcard ? below by A, it should work:

public class B {
    private A<? extends A> a;

    public <T extends A<T>> void setA(T a) {
        this.a = a;
    }
}

这篇关于Java字段类型是否为一般递归自我类型的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆