4

我对Java(版本6)中的模板和静态方法有问题,这可能分为两个子问题:

首先,我需要找到一种方法如何返回一个模板化Iterable的(脱离静态上下文),在每次迭代中创建一个抽象类(例如,A)的某个子类(例如,B)的新实例。(背景:我需要将一个对象(例如,一个字符串)从一个可迭代对象转换为另一个对象)。我找到了一种使用模板/泛型的方法:

import java.util.HashSet;
import java.util.Iterator;

public class Test {

    public static <T extends A> Iterable<T> getIterable(final Iterator<String> i) {

        return new Iterable<T>() {

            public Iterator<T> iterator() {

                return new Iterator<T>() {

                    public boolean hasNext() {
                        return i.hasNext();
                    }

                    public T next() {
                        try {
                            /* this is where things go wrong:        *
                             * T is considered as class A and not B  */
                            return T.factory(i.next());
                        } catch (Exception e) {
                            e.printStackTrace();
                            return null;
                        }
                    }

                    public void remove() {
                        i.remove();
                    }        
                };

            }

       };

    }

    public static void main(String[] args) {

        HashSet<String> st = new HashSet<String>();
        st.add("x1");

        Iterable<B> bi = getIterable(st.iterator());
        for (B b : bi)
        {
            System.out.println(b);
        }
    }
}

此外,我定义了以下类层次结构:

/* super class */
abstract class A
{
    public static <T extends A> T factory(String c)
    {
         /* returns nothing, should never be called */
         return null;
    }
}

/* child class */
class B extends A
{
    String s;
    public B (String s) { this.s = s; }

    public static B factory(String s)
    {
        return new B(s);
    }
}

整体方式似乎有效(原则上)。但是,调用的静态方法factory将始终是超类 A 中的方法,即使模板T是 B 类型。

我正在寻找关于如何调用子类的工厂的任何想法/建议,即模板附带的类<T>(例如,B)。非常感谢任何帮助!

(注意:我发现在 Java 7 中,可以使用接口并继承/覆盖静态方法,但我绑定到 Java 6 ...)

4

1 回答 1

3

Java 关键字static对编译器有意义:它允许编译器在编译时将方法调用静态绑定到方法。因此,编译器在编译行时将对方法的调用写入生成的字节码A.factory(String)return T.factory(i.next()).

您显然希望在运行程序时覆盖 B 中的工厂方法以具有动态行为。对于该行为,您必须删除该static关键字。

于 2013-07-12T12:17:33.827 回答