简体   繁体   English

是否可以从模板类参数获取公共静态字段?

[英]Is it possible to get public static field from template class argument?

Given 特定

class A {
   public static A newInstance(int x) { ... }
}

And several classes containing static fields of type A 还有几个包含A型静态字段的类

class B1 {
   public static A MIN = A.newInstance(10);
}

class B2 {
   public static A MIN = A.newInstance(15);
}

I would like to parameterize a class with B1 or B2 to get MIN field of type A from class B in the class C : 我想参数化类用B1B2获得MIN类型的字段A从类B在类C

class C <T, P> {
   private T t = ???;
}

When C<A, B1> c = new C(); C<A, B1> c = new C(); what should be placed instead ??? 应该放置什么呢??? to get B1.MIN ? 得到B1.MIN Is it possible? 可能吗?

EDIT: Thank you for the answers, I have upvoted both. 编辑:谢谢你的答案,我都赞成。 I have arrived simply at 我只是到达

class C <T, P> {
   private T t;

   public C(T min) {
      this.t = min;
   }
}

This will be just C<A, B1> c = new C<A, B1>(B1.MIN); 这将只是C<A, B1> c = new C<A, B1>(B1.MIN); because as you can see it is hard to avoid a constructor for C taking an instance of B1 or smth like that. 因为如您所见,很难避免C的构造函数采用这样的B1或smth的实例。 But in this case B1 at least not instantiated. 但是在这种情况下, B1至少没有实例化。

You can use an interface to achieve this behavior: 您可以使用接口来实现此行为:

class A {
    public static A newInstance() { return new A(); }
}

interface HasMin {
    public static A MIN = null;
}

class B1 implements HasMin {
    public static A MIN = A.newInstance();
}

class B2 implements HasMin {
    public static A MIN = A.newInstance();
}

class C<T extends HasMin> { 
    private A t = T.MIN; 
}

Then you can create: C<B1> and C<B2> and use both. 然后,您可以创建: C<B1>C<B2>并同时使用。

As Tom suggested in the comments below, this approach is limited to use static fields. 正如Tom在下面的评论中建议的那样,此方法仅限于使用静态字段。 An even better approach would be: 更好的方法是:

public class Play {

    public static void main(String[] args) {
        B1 b1 = new B1();
        C<B1> c = new C<>(b1);
        System.out.println(c.getA());  // prints: A{ x=10 }

        B2 b2 = new B2();
        C<B2> c2 = new C<>(b2);
        System.out.println(c2.getA()); // prints: A{ x=20 }
    }
}

class A {
    private int x;

    public A(int x) {
        this.x = x;
    }

    @Override
    public String toString() {
        return "A{ x=" + x + " }";
    }

    public static A newInstance(int x) {
        return new A(x);
    }
}

interface GetMin {
    public A getMin();
}

class B1 implements GetMin {
    public A MIN = A.newInstance(10);

    @Override
    public A getMin() {
        return MIN;
    }
}

class B2 implements GetMin {
    public A MIN = A.newInstance(20);

    @Override
    public A getMin() {
        return MIN;
    }
}

class C<T extends GetMin> {
    private A a = null;

    public C(T t) {
        a = t.getMin();
    }

    public A getA() {
        return a;
    }
}

I would forget static and have a concrete instance of an interface: 我会忘记静态的,并拥有接口的具体实例:

public interface Bounds<T> {
    T min();
}

The concrete instance could be singleton, so next best thing to a static: 具体实例可能是单例,因此静态的第二件事是:

public enum B implements Bounds<A> {
    INSTANCE;

    private final A min = A.newInstance(10);

    @Override
    public A min() {
        return min;
    }
}

C then defined like so: C然后这样定义:

public class C<T, P extends Bounds<T>> {

    private T min;

    public C(P bounds) {
        min = bounds.min();
    }

    public T getMin() {
        return min;
    }
}

Usage: 用法:

C<A, B> c = new C(B.INSTANCE);

Self describing 自我描述

Maybe you don't want this meta data type ( B ), maybe you want types to describe themselves. 也许您不希望这种元数据类型( B ),也许您希望类型描述自己。 So C could be defined for types that can describe their own bounds: 因此,可以为可以描述其自身界限的类型定义C

public class C<T extends Bounds<T>> {

    private T min;

    public C(T anyT) {
        min = anyT.min();
    }

    public T getMin() {
        return min;
    }
}

Usage: 用法:

C<A> c = new C(A.zero); //any A will do

Where A is: 其中A是:

public class A implements Bounds<A>{
    public final static A zero = A.newInstance(0);

    private final static A min = A.newInstance(10);

    public static A newInstance(int x) {
        return new A(x);
    }

    private int x;

    public A(int x) {
        this.x = x;
    }

    @Override
    public A min() {
        return min;
    }
}

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

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