首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java的泛型编程与多态,重载的同与不同

摘要: 从字节码看Java的泛型编程与多态,重载的同于不同。

泛型编程

泛型编程在某些语言中也称之为模板编程,比如C ++,所以在泛型编程中见到的那个Ť也就是模板的首字母。

来看一个泛型编程的简单样例。

public static void main(String [] args){ StringBuilder sb = new StringBuilder(“Test template”); 的System.out.println(FOO(SB)的ToString()); } public static T foo(T t){// bla bla bla return t; }

泛型编程与多态

在面向对象的编程中还有一个概念叫多态,利用这种概念,我们可以将泛型编程中的Ť替换成所有对象的基类对象,这在某种程度上同样能够达到泛型编程所达到的效果,如下方代码所示。

public static void main(String [] args){ StringBuilder sb = new StringBuilder(“Test template”); 的System.out.println(FOO(SB)的ToString()); 的System.out.println(foo2的(SB)的ToString()); } public static T foo(T t){// bla bla bla return t; } public static Object foo2(Object o){// bla bla bla return o; }

那么这两种方法有什么区别吗?

我们来看看字节码。

public class template.Template { public template.Template(); 代码:0:aload_0 1:invokespecial#1 //方法java / lang / Object。“”:()V 4:return public static void main(java.lang.String []); 代码:0:new#2 // class java / lang / StringBuilder 3:dup 4:ldc#3 // String测试模板 6:invokespecial#4 //方法java / lang / StringBuilder“”:( Ljava / lang / String;)V 9:astore_1 10:getstatic#5 // Field java / lang / System.out:Ljava / io / PrintStream; 13:aload_1 14:invokestatic#6 //方法foo :( Ljava / lang / Object;)Ljava / lang / Object; 17:checkcast#2 // class java / lang / StringBuilder 20:invokevirtual#7 //方法java / lang / StringBuilder.toString :()Ljava / lang / String; 23:invokevirtual#8 //方法java / io / PrintStream.println :( Ljava / lang / String;)V 26:getstatic#5 // Field java / lang / System.out:Ljava / io / PrintStream; 29:aload_1 30:invokestatic#9 //方法foo2:(Ljava / lang / Object;)Ljava / lang / Object; 33:invokevirtual#10 //方法java / lang / Object.toString :()Ljava / lang / String; 36:invokevirtual#8 //方法java / io / PrintStream.println:(Ljava / lang / String;)V 39:返回 public static T foo(T); 代码:0:aload_0 1:areturn public static java.lang.Object foo2(java.lang.Object); 代码:0:aload_0 1:areturn }

FOO方法调用时的字节码

14:invokestatic#6 //方法foo :( Ljava / lang / Object;)Ljava / lang / Object; 17:checkcast#2 // class java / lang / StringBuilder20:invokevirtual#7 //方法java / lang / StringBuilder。的toString :()Ljava /郎/字符串;

foo2的方法调用时的字节码

30:invokestatic#9 //方法foo2 :( Ljava / lang / Object;)Ljava / lang / Object; 33:invokevirtual#10 //方法java / lang / Object.toString :()Ljava / lang / String;

不难发现,主函数调用使用了泛型编程的FOO方法时,其字节码已不再是T,而是替换为实际的StringBuilder的类;反观foo2的方法使用的还是对象,那它将是在运行时作类型转换。

结论:泛型编程是编译期替换;多态则是运行期作类型转换。

泛型编程与重载

什么是重载

不废话,形如下方代码即重载。

public static int add(int a,int b) public static double add(double a,double b)

重载的特点:两个及以上方法名相同;参数个数不同,参数顺序不同,类型不同,以上任一种及以上都可以构成重载仅返回值不同不可构成重载。

测试的完整代码如下:

public static void main(String [] args){ StringBuilder sb = new StringBuilder(“Test template”); 的System.out.println(FOO(SB)的ToString()); 的System.out.println(foo2的(SB)的ToString()); int a = 1; int b = 2; System.out.println(add(a,b)); double x = 1.1; 双y = 1.2; System.out.println(add(x,y)); } public static T foo(T t){// bla bla bla return t; } public static Object foo2(Object o){// bla bla bla return o; } public static int add(int a,int b) public static double add(double a,double b)

接下来看看重载部分的字节码:

48:invokestatic#11 //方法添加:(II)I71:invokestatic#17 //方法add :((DD)D)

总结:看来字节码已经做了相应的转换,重载和泛型编程相似,都是在编译期就做了替换,而不是在运行时,但是重载需要为每一种不同的参数类型重新编写代码,代码复用度不高。

总结

泛型编程和重载是在编译期作了类型替换,多态则是在运行期作类型转换。

泛型编程和多态代码复用度高,重载代码复用度低。

当然,泛型,重载,多态更有其它设计模式的意义,在此不作讨论。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180606A15MXL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券