【问题标题】:Java: can't catch exception with getConstructor()Java:无法使用 getConstructor() 捕获异常
【发布时间】:2019-12-15 19:15:51
【问题描述】:

我编写了一个抽象类“Card”,其中包含两个子类“Sticker”和“PlayingCard”。 “PlayingCard”类有一个名为“Color”属性的枚举对象,它基本上说明了它是什么类型的牌(红心、黑桃……)。在这个枚举中,我有一个基于字符串返回对象的方法:如果我将字符串“黑桃”传递给它,它将返回一个包含黑桃的对象。如果传递给它的字符串不作为卡片类型存在(所以不是红桃、黑桃等),它会抛出一个自制的“TypeUnknownException”。这个异常只是调用它的 super(String message)。

现在,当在另一个类中读取文件并生成 Card 对象时:

Card c= (Card) Class.forName(one).getConstructor(String.class, double.class).newInstance(two, three);

one 是 txt 文件中的字符串(始终是一个已实现的类名,如 Sticker 或 Playingcard,two 是来自 txt 文件的字符串(应该是一种像黑桃一样的牌,但可以不同,应该抛出异常,用这个字符串作为消息)和 three 是从 txt 文件中解析的双精度数。

这会从 Sticker 或 PlayingCard 调用构造函数。当它从 PlayingCard 调用构造函数时,它应该能够抛出我的“TypeUnknownException”,所以我可以捕获它以将其添加到一串错误消息中以在最后打印出来。但是,当我尝试捕获该异常时,编译器说它永远不会被抛出。 我知道这是因为它还不知道它可以调用一个抛出我的异常的构造函数,但是有没有办法捕获它,并且只有那个异常(不能全部捕获,它必须抛出其他异常)?

供参考:PlayingCard 类中的代码:

public PlayingCard(String col, double worth) throws TypeUnknownException{
   this(col,(int)worth);
}

PlayingCards 只取整数作为它的值,但由于 Card 类必须取双精度,所以上面有额外的构造函数

public PlayingCard(String col, int w) throws TypeUnknownException{
    this.color= Color.getColorWithName(col.toUpperCase());
    this.worth= w;}

以及枚举Color中的getColorWithName方法:

public static Color getColorWithName(String name) throws TypeUnknownException{
    if(name.equalsIgnoreCase("Spades")){return SPADES;}
    else if(name.equalsIgnoreCase("Hearts")){return HEARTS;}
    else if(name.equalsIgnoreCase("Clovers")){return CLOVERS;}
    else if(name.equalsIgnoreCase("Tiles")){return TILES;}
    else throw new TypeUnknownException(name);
}

其他可能有用的东西:当我在异常的构造函数中添加打印时,它能够打印不存在的卡片类型的名称。所以肯定会抛出异常,我只是不知道如何捕获它。

编辑:因为有评论,我意识到我忘了提到在捕获 InvocationTargetException 时(或者甚至是全部捕获)总是给我消息“null”。

Edit2:回答:问题在于方法 getMessage() 不适用于包装类 InvocationTargetException。使用 getTargetException().getMessage() 时,代码工作正常。感谢用户:207421 的帮助。

【问题讨论】:

  • 您考虑过查阅 Javadoc 吗?它明确指出newInstance() 将构造函数抛出的异常包装到InvocationTargetException 中。
  • 我想我应该提到,当捕获调用时,它的消息总是“null”,而不是它应该是什么
  • 没关系,我明白了。我不知道我不能在包装的异常上使用 getMessage() 。感谢您的回复,它让我再次思考这让我能够解决它。我感谢在一个不完整且表述不完善的问题上所做的努力。
  • 你应该做的真正的事情是停止使用反射。只需获取 one 的值并使用简单的 if/else 或 switch 来实例化正确的类,无需反射。
  • 我已经找到了答案,如新编辑中所示。不过,我很欣赏评论。这是我的 uni 课程的可扩展性练习,因此反思是必要的(尽管我同意在现实世界的示例中,这对于两个硬编码的课程来说太过分了)。

标签: java exception reflection constructor


【解决方案1】:

问题在于方法 getMessage() 不适用于包装类 InvocationTargetException。我对 java API 的缺乏经验让我忽略了这一点。使用 getTargetException().getMessage() 时,代码工作正常。感谢https://stackoverflow.com/users/207421/user207421 的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2021-10-14
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2010-10-29
    相关资源
    最近更新 更多