Java如何避免类型转换

小屋:

我过去几次遇到过这个问题,但是并没有真正找到一个好的解决方案/设计。

下面的示例代码将从实体(公司或文章)生成PDF文档

public class Entity
{
    int id;
}

public class Company extends Entity
{
    private String HQ;
}

public class Article extends Entity
{
    private String title;
}

public interface EntityPDFGenerator
{
    void generate(Entity entity);
}

public class ArticlePDFGenerator implements EntityPDFGenerator
{
    public void generate(Entity entity)
    {
        Article article = (Article) entity;
        // create Article related PDF from entity
    }
}

public class CompanyPDFGenerator implements EntityPDFGenerator
{
    public void generate(Entity entity)
    {
        Company company = (Company) entity;
        // create Company related PDF
    }
}

主班:

public class PDFGenerator
{
    public void generate(Entity entity)
    {
        EntityPDFGenerator pdfGenerator = getConcretePDFGenerator(entity);
        pdfGenerator.generate(entity);

    }

    // lets make the factory task simple for now
    EntityPDFGenerator getConcretePDFGenerator(Entity entity)
    {
        if(entity instanceof Article){
            return new ArticlePDFGenerator();
        }else{
            return new CompanyPDFGenerator();
        }
    }
}

在上述方法中,问题在于将Entity强制转换为具体类型(在代码的后期阶段进行铸造可能很危险)。我尝试使用泛型来实现,但随后得到警告

未经检查的“ generate(T)”调用

我可以改善此代码吗?

Tamas Rev:

简短答案

泛型不是这里的正确工具。您可以使转换明确:

public class CompanyPDFGenerator implements EntityPDFGenerator
{
    public void generate(Entity entity)
    {
        if (! (entity instanceof Company)) {
            throw new IllegalArgumentException("CompanyPDFGenerator works with Company object. You provided " + (entity == null ? "null" : entity.getClass().getName()));
        }
        Company company = (Company) entity;
        System.out.println(company);
        // create Company related PDF
    }
}

或者,您可以在实体类中定义某种数据结构,并仅在打印机中使用它:

public abstract class Entity
{
    int id;
    public abstract EntityPdfData getPdfData();
}

// ...

public class CompanyPDFGenerator implements EntityPDFGenerator
{
    public void generate(Entity entity)
    {
        EntityPdfData entityPdfData = entity.getPdfData();
        // create Company related PDF
    }
}

长答案

如果您在编译时知道类型,则泛型很有用。即是否可以将实际类型写入程序。对于列表,它看起来很简单:

// now you know at compile time that you need a list of integers
List<Integer> list = new ArrayList<>();

在您的示例中,您不知道:

public void generate(Entity entity)
{
    // either Article or Company can come it. It's a general method
    EntityPDFGenerator pdfGenerator = getConcretePDFGenerator(entity);
    pdfGenerator.generate(entity);

}

假设您要向中添加type EntityPDFGenerator,如下所示:

public static interface EntityPDFGenerator<T extends Entity>
{
    void generate(T entity);
}

public static class ArticlePDFGenerator implements EntityPDFGenerator<Article>
{
    public void generate(Article entity)
    {
        Article article = (Article) entity;
        // create Article related PDF from entity
    }
}

public static class CompanyPDFGenerator implements EntityPDFGenerator<Company>
{
    public void generate(Company entity)
    {
        Company company = (Company) entity;
        // create Company related PDF
    }
}

看起来不错 但是,找到合适的发电机将非常棘手。Java泛型是不变的。甚至ArrayList<Integer>不是的子类ArrayList<Number>因此,ArticlePdfGenerator不是的子类EntityPDFGenerator<T extends Entity>即,这将无法编译:

<T extends Entity> EntityPDFGenerator<T> getConcretePDFGenerator(T entity, Class<T> classToken)
{
    if(entity instanceof Article){
        return new ArticlePDFGenerator();
    }else{
        return new CompanyPDFGenerator();
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何避免类型转换警告?

Java泛型语法如何帮助避免类型转换?

避免类型转换

如何避免使用广义类型约束进行强制转换?

避免Java类型擦除

如何强制强制转换类型的字典以避免分配中的不兼容类型

如何避免在java中的子类中进行强制转换

尝试扩展Java对象时如何避免向下转换

重构代码以避免类型转换

需要帮助以避免类型转换

如何在Java中将String类型转换为Class类型

Java:如何将Instant类型转换为XMLGregorianCalendar类型?

如何避免VARCHAR隐式类型转换为VARCHAR2使用Hibernate?

如何避免警告类型安全:未经检查就从Object强制转换为ArrayList <Facility>

在熊猫DataFrame中将某些值替换为NaN时,如何避免数据类型转换?

如何避免使用目标类型为List <String>的Spring ConversionService进行强制转换?

如何避免:“ List类型的表达式需要未经检查的转换才能符合。”

如何在将模板转换为任意类型时避免编译器错误

如何在函数参数中强制执行类型并避免隐式转换?

如何避免丢失类型信息

如何避免角度类型错误?

如何避免类型参数擦除

如何避免装箱值类型

在Java中,如何在泛型类型的实例上调用getClass时避免原始类型?

如何将泛型类型存储在缓存中,以避免检索时未经检查的强制类型转换?

避免将Int转换为double类型转换舍入?

如何从擦除类型转换类型

Java Math 类型转换

Java类型转换问题