Java泛型 - 类型推导

Shm*_*opy 11 java generics

考虑以下:

 public class GenericTest {
    static void print(int x) {
        System.out.println("Int: " + x);
    }
    static void print(String x) {
        System.out.println("String: " + x);
    }

    static void print(Object x) {
        System.out.println("Object: " + x);
    }

    static <T> void printWithClass(T t) {
        print(t);
    }
    public static void main(String argsp[]) {
        printWithClass("abc");
    }
}
Run Code Online (Sandbox Code Playgroud)

它打印Object:abc.为什么不打印字符串:abc?

das*_*ght 10

这是因为Java类型擦除:你的

static <T> void printWithClass(T t) {
    print(t);
}
Run Code Online (Sandbox Code Playgroud)

实际上是一个语法糖

static void printWithClass(Object t) {
    print(t);
}
Run Code Online (Sandbox Code Playgroud)

公平地说,"语法糖"让编译器做了一些非常好的和重要的检查,但是在运行时只有一个printWithClass方法的副本,它java.lang.Object用作变量的类型t.

如果您使用其他语言(C#,C++模板,Ada)中的泛型,那么类型擦除将与您所知道的相反,但这就是它在封面下的工作方式.


Sco*_*ion 4

Java支持方法重写(动态类型绑定),但不支持你想要实现的(重载是静态多态性而不是动态的)。

为了在Java中实现你想要实现的目标,你需要双重调度。

访问者模式应该是你的朋友。

我已经给你写了一个代码示例。

public class Test {

    public static void main(String argsp[]) {
        PrintTypeImpl typeImpl = new PrintTypeImpl(new StringType(), new IntType(), new ObjectType());
        typeImpl.accept(new PrintVisitor());
    }

    static final class PrintVisitor implements TypeVisitor {
        public void visit(IntType x) {
            System.out.println("Int: ");
        }

        public void visit(StringType x) {
            System.out.println("String: ");
        }

        public void visit(ObjectType x) {
            System.out.println("Object: ");
        }
    }

    interface TypeVisitor {
        void visit(IntType i);

        void visit(StringType str);

        void visit(ObjectType obj);
    }

    interface PrintType {
        void accept(TypeVisitor visitor);
    }

    static class StringType implements PrintType {
        @Override
        public void accept(TypeVisitor visitor) {
            visitor.visit(this);
        }
    }

    static class ObjectType implements PrintType {
        @Override
        public void accept(TypeVisitor visitor) {
            visitor.visit(this);
        }
    }

    static class IntType implements PrintType {
        @Override
        public void accept(TypeVisitor visitor) {
            visitor.visit(this);
        }
    }

    static final class PrintTypeImpl implements PrintType {

        PrintType[] type;

        private PrintTypeImpl(PrintType... types) {
            type = types;
        }

        @Override
        public void accept(TypeVisitor visitor) {
            for (int i = 0; i < type.length; i++) {
                type[i].accept(visitor);
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)