java动态模型转换_Java中的动态转换

java动态模型转换

我是Baeldung博客的忠实粉丝。 他的最新文章之一是有关Java的转换。 不幸的是,我觉得它错过了一个重要点:动态转换。 由于那是(非常) 相对较新的,因此本文将尽力填补这一空白。

不要使用投射

第一件事是避免铸造应该相对容易。

使用多态

多态是不强制转换的好方法。 考虑以下代码:

Listanimals=newArrayList();
animals.add(newCat());
animals.add(newDog());
for(Animalanimal:animals){
    if(animalinstanceofCat){
        ((Cat)animal).mew();
    }elseif(animalinstanceofDog){
        ((Dog)animal).bark();
    }elseif(animalinstanceofSnake){
        ((Snake)animal).hiss();
    }
}

如果集合中的所有对象类型都继承自单个类型,则可以使用多态。 只需在此单一类型中添加一个方法并在子类型中覆盖它即可。

publicabstractclassAnimal{
    publicabstractvoidmakeSound();
}

publicclassDog{
    @OverridepublicvoidmakeSound(){
        bark();
    }
}

publicclassCat{
    @OverridepublicvoidmakeSound(){
        mew();
    }
}

使用泛型

多态不能总是应用。 例如,在以下情况下就是这种情况:

  • 项目不是相关类型的实例
  • 父类型不在我们的控制范围内
  • 等等

在这些情况下,泛型是避免强制转换的另一种方法。

在Java 5之前,以下代码将成为规范:

Listdates=newArrayList();
dates.add(newDate());
Objectobject=dates.get(0);
Datedate=(Date)object; (1)
  1. 需要投放。 尽管运行时类型为Date ,但编译器无法了解它。

使用泛型,可以重写以上代码:

List<Date>dates=newArrayList<>();
dates.add(newDate());
Datedate=dates.get(0); (1)
  1. 无需强制转换:由于泛型,编译器具有足够的信息。

强制转换时

尽管有一些狂热者认为,但有时铸件不容忽视。

这样的用例之一就是Servlet API。 Servlet上下文/请求/会话中的映射存储对象不使用泛型 。 即使这样做,他们也会使用Object

// In a servlet
ServletContextcontext=getServletContext();
context.put("date",newDate());

// Somewhere else
ServletContextcontext=getServletContext();
Objectobject=context.get("date");
Datedate=(Date)object;

动态铸造

最初可用的唯一铸造形式是静态铸造。 这意味着在编译时需要知道转换类型。 例如,让我们想象一个方法,该方法接受Stream<Object> ,过滤特定类型的所有元素并以正确的类型返回这些元素。 这是用法示例:

List<?>items=...
List<Date>dates=filter(Date.class,items);

无法通过静态转换来实现filter方法。 实际上有两个问题:

  1. instanceof运算符需要类型,而不是Class实例, 例如 item instanceof Date
  2. 强制转换语法, 例如 (Date) item

可以用对Class.isInstance(Object)的调用来替换instanceof运算符(自JDK 1.1开始)。 如果没有广泛使用,这是众所周知的。

但是,用于替换强制转换语法的API更为“最新”。 自JDK 1.5起就有一个Class.cast(Object)方法。它是围绕旧语法的简单包装。

使用这两种方法,最终可以实现上面的filter方法。

static<T>List<T>filter(Class<T>clazz,List<?>items){
    returnitems.stream()
        .filter(clazz::isInstance)
        .map(clazz::cast)
        .collect(Collectors.toList());
}

使用强制转换API允许动态强制转换。 没有它,就不可能实现上述方法。

结论

尽管生态系统之外的许多人都认为Java是进化的,即使不是很快。 但是,开发人员需要熟悉每个版本提供的新功能。

翻译自: https://blog.frankel.ch/dynamic-casting-java/

java动态模型转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值