从泛型方法问题重载方法召唤 [英] Call of overloaded method from generic method issue

查看:256
本文介绍了从泛型方法问题重载方法召唤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我碰到的有趣的事情(工作在Java和C#一样的)。
Java代码:

I've run into interesting thing (works same in both Java and C#). Java code:

public class TestStuff {

    public static void main(String[] args) {
        Printer p = new PrinterImpl();
        p.genericPrint(new B());    
    }

}

class PrinterImpl implements Printer {

    void print(A a) {
        System.out.println("a");
    }

    void print(B b) {
        System.out.println("b");
    }

    @Override
    public <T extends A> void genericPrint(T b) {
        print(b);
    }

}

interface Printer {
    public <T extends A> void genericPrint(T a);
}

class A {

}

class B extends A{

}

C#代码:

namespace TestStuff
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var printer = new Printer();
            printer.GenericPrint(new B());
        }

    }

    public class Printer
    {

        public void Print(A a)
        {
            Console.WriteLine("a");
        }

        public void Print(B b)
        {
            Console.WriteLine("b");
        }

        public void GenericPrint<T>(T a) where T : A
        {
            Print(a);
        }

    }

    public class B : A
    {

    }

    public class A
    {

    }

}

当我写了这样的事情我期望看到的b印在两种情况下。
但是,正如你所看到的,它是一个什么是打印出来。

When I wrote something like this I expected to see "b" printed in both cases. But, as you can see, it is "a" what is printed.

我读过C#语言规范和它说重载的方法是在选择编译时。这解释了为什么它工作的方式。

I've read C# language specification and it says overloaded method is selected at compile-time. It explains why it works that way.

不过,我没有时间去检查它在Java语言规范。

However, I had no time to check it out in Java language specification.

可能有人请给一个发生了什么以及为什么更详细的解释?我怎么能达到我想要的东西提前?

Could somebody please give a more detailed explanation of what is happening and why? And how could I achieve what I wanted?

谢谢!

推荐答案

关键是要明白,仿制药仅适用于在Java编译时。它是编译器编译时只使用语法糖,但丢弃而生成的类文件

The key is to understand that generics are only available at compile time in java. It is just syntax sugar that the compiler uses while compiling, but throws away while generating the class files.

这样,代码:

   public <T extends A> void genericPrint(T b) {
      print(b);
   }



被编译为:

is compiled into:

   public void genericPrint(A b) {
      print(b);
   }



由于参数打印是A型,重载版本打印(A一)是一个解决。我建议对A的实例或href=\"http://en.wikipedia.org/wiki/Visitor_pattern\" rel=\"nofollow\">访问者模式的回调到PrinterImpl为

Since the argument to print is of type A, the overloaded version print(A a) is the one resolved. I'd suggest using polymorphic calls on instances of A or the Visitor pattern to callback into PrinterImpl for your use case.

是这样的:

interface Visitor {
   void visit(A a);

   void visit(B b);
}

class PrinterImpl implements Printer, Visitor {

   void print(A a) {
      System.out.println("a");
   }

   void print(B b) {
      System.out.println("b");
   }

   public <T extends A> void genericPrint(T b) {
      b.accept(this);
   }

   public void visit(A a) {
      print(a);
   }

   public void visit(B b) {
      print(b);
   }
}

interface Printer {
   public <T extends A> void genericPrint(T a);
}

class A {
   public void accept(Visitor v) {
      v.visit(this);
   }
}

class B extends A {
   public void accept(Visitor v) {
      v.visit(this);
   }
}

这篇关于从泛型方法问题重载方法召唤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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