Javaer初识Dart:我们不一样 (二 )

前言

文章中Java的版本是1.8,Dart版本是3.3.1 。 

 Java或者Dart版本的变化可能会导致对比项的结果变化。

泛型

泛型的定义:具有某一类或某一组事物的特征或与其有关;不制定具体类型。

泛型通常是类型安全所必需的,但它们的好处不仅仅是让您的代码运行:

  1. 正确指定泛型类型可以生成更好的代码。
  2. 您可以使用泛型来减少代码重复。

按照惯例,大多数类型变量都有单字母名称,如 E、 T、 S、 K 和 V。 看下面Cache的事例:

 

kotlin

代码解读

复制代码

class Pair<A, B, C> { final A value1; final B value2; final C value3; Pair(this.value1, this.value2, this.value3); } class Cache<T> { final T data; Cache(this.data); T getData() { return data; } } void main() { print("main"); var pair1 = Pair('a', 'b', 'c'); var pair2 = Pair('a', 10, 30); var cache = Cache('caicai'); print(cache.getData()); var cache2 = Cache(30); print(cache2.getData()); }

Cache类指定了泛型T,方法getData返回 T,在实际方法调用的时候返回的实际类型,如上面cache.getData()实际类型是String;cache2.getData()实际类型是Int。这样减少了工程师实际类型转换的过程中出错。如果没有泛型这个功能,我们增加很多包含各种数据类型的代码,如下图所示:

 

kotlin

代码解读

复制代码

class CacheString { final String data; CacheString(this.data); String getData() { return data; } } class CacheInt { final int data; CacheInt(this.data); int getData() { return data; } }

类型擦除

Java泛型会受到类型擦除的影响,这意味着泛型类型信息会在运行时被删除。这允许向后兼容不支持泛型的旧版 Java。但是,这也意味着您无法在运行时使用反射来确定泛型参数的实际类型。(Java是伪泛型) Dart泛型不使用类型擦除。泛型类型信息在运行时保留,这允许您检查和使用实际类型。在Dart中,类型信息(String)在运行时可用,允许进行运行时类型检查。如下面的代码所示:

 

swift

代码解读

复制代码

List<String> list = []; if (list is List<String>) { // This will work in Dart }

泛型约束

实现泛型类型时,您可能希望限制可以作为参数提供的类型,以便参数必须是特定类型的子类型。您可以使用 extends来实现这一点。如下面的示例中,Foo泛型可以定义SomeBaseClass以及SomeBaseClass的子类,Foo泛型指定任何非SomBaseClass的子类都会导致编译错误,如果指定为Object,则会编译错误。

这边整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】免费获取

scala

代码解读

复制代码

class SomeBaseClass { } class Foo<T extends SomeBaseClass> { // Implementation goes here... String toString() => "Instance of 'Foo<$T>'"; } class Extender extends SomeBaseClass { } void prints(List<num> nums) { nums.forEach(print); } void main() { var someBaseClassFoo = Foo<SomeBaseClass>(); var extenderFoo = Foo<Extender>(); List<num> n = [10, 20.0]; List<int> ages = [10, 20, 30]; int age = 30; prints(n); prints(ages); print(age is num); print(ages is List<num>); print(extenderFoo is Foo<SomeBaseClass>); n = ages; var foo = Foo(); print(foo); // Instance of 'Foo<SomeBaseClass>' }

注意:Java不支持运行时泛型检查类型,Dart支持运行时泛型检查。如上面例子中的ages is List。Java泛型有类型擦除,List<Object>和List<String>类型是相同的;Dart没有类型擦除功能,String是Object子类,而List<String>同样也是List<Object>的子类。

泛型方法

在Java中,可以通过在返回类型之前指定类型参数来在类中定义泛型方法。如下面代码所示:

 

csharp

代码解读

复制代码

public <T> void print(T item) { System.out.println(item); }

Dart使用类似的语法,但是类型参数是在方法名称后定义的。

 

csharp

代码解读

复制代码

void printItem<T>(T item) { print(item); }

扩展方法

扩展方法为现有库添加了功能。您可能在不知情的情况下使用了扩展方法。例如,当您在IDE中使用代码完成时,它会在常规方法旁边建议扩展方法。扩展方法相当于在原来的类的基础上增加新的逻辑,新的方法。如果没有扩展方法,我们需要增加新的wrapper类,包装原有的类来实现方法;我们也可以新增新的helper方法来实现需要实现的方法;前面这两种方法在多人开发时候会定义多个wrapper类或者helper方法。

扩展方法如何实现,定义如下面所示:

 

dart

代码解读

复制代码

extension <extension name>? on <type> { // <extension-name> is optional (<member definition>)* // Can provide one or more <member definition>. }

示例代码如下:

 

dart

代码解读

复制代码

extension MyFancyList<T> on List<T> { int get doubleLength => length * 2; List<T> operator -() => reversed.toList(); List<List<T>> split(int at) => [sublist(0, at), sublist(at)]; }

总结

泛型是软件开发过程中一个很繁琐和高深的功能,能够高效地使用泛型会让程序更加高效,能够使可读性更好。扩展方法相当于在原来的类里面增加新的逻辑和方法。希望文章对您有帮助,如果文中有问题,希望您不吝指教。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值