有没有办法在 Java 中推断泛型类型?

Is there a way to infer generic types in Java?

我想创建一个通用方法来发送带附件的电子邮件,我正在考虑使用这样的方法:

public class MailAttachment<T> {

    private String attachmentName;
    private T attachment;

    public MailAttachment(String attachmentName, T attachment) {
        super();
        this.attachmentName = attachmentName;
        this.attachment = attachment;
    }
    //Getters and setters

}

稍后发送泛型,让Java在编译时决定发送的实例类型。但是编译器添加了一个错误,指出需要将其转换为正确的类型(File、DataSource、InputStreamSource)。

   @Autowired
    private JavaMailSender mailSender;

 public void sendHtmlMail(Mail mail, MailAttachment<?> attachment) {
            new Thread(() -> {
                try {
                    MimeMessage message = mailSender.createMimeMessage();
                    MimeMessageHelper helper = new MimeMessageHelper(message, true);

                    helper.setTo(mail.getTo());
                    helper.setSubject(mail.getSubject());
                    helper.setFrom(host);
                    message.setContent(mail.getContent(), "text/html");
                    if (attachment != null) {    
                        //Casting error 
                   helper.addAttachment(attachment.getAttachmentName(), attachment.getAttachment());
                    }
                    mailSender.send(message);
                } catch (MessagingException | MailException e) {
                    logger.error("Error sending email: ", e);
                }
            }).start();
        }

所以我不得不使用变通方法来验证并转换为正确的类型,如下所示:

if (attachment.getAttachment() instanceof DataSource) {
    helper.addAttachment(attachment.getAttachmentName(),
                        (DataSource) attachment.getAttachment());
} else if (attachment.getAttachment() instanceof File) {
    helper.addAttachment(attachment.getAttachmentName(),
                        (File) attachment.getAttachment());
} else if (attachment.getAttachment() instanceof InputStreamSource) {
    helper.addAttachment(attachment.getAttachmentName(),
                        (InputStreamSource) attachment.getAttachment());
}

所以,我想知道是否有更好的方法来仅使用此方法检查此类内容,同时在参数中保留泛型类型?

创建可附加的接口:

interface Attachable {
  void attach(Helper helper);
}

然后为各种类型实现:

class DataSourceAttachable implements Attachable {
  String name;
  DataSource dataSource;  // Initialize in ctor.

  void attach(Helper helper) {
    helper.addAttachment(name, dataSource);
  }
}

// etc, for other types

那就不需要泛型了:

public void sendHtmlMail(Mail mail, Attachable attachable) {
  // ...
  attachable.attach(helper);
  // ...
}