【问题标题】:instanceof vs equals on defined string that identifies the Classinstanceof vs equals 定义了标识类的字符串
【发布时间】:2014-04-23 23:44:24
【问题描述】:

我可以在使用instanceof 的程序中测试班级类型,或者获取一个标识班级关系的字段。所以选择是在

if(myObjec instanceof Something){
} 

if(myObjec.geClassType().equals("Something")){
}

就效率而言,什么是最好的?

geClassType() 是我正在工作的程序对象中存在的一种方法(不是标准的 java 方法),并且是一种返回带有类名的字符串的方法。创建对象时,名称作为字段传递

编辑 我在代码的第二个示例中得到的字段并不能准确识别类,而是一个类别,并且也用于不同的例程,但我也可以将其用于此目的,因为我为每个类别使用了一个特定的对象。 所以我将此报告为getClassType,以使我的问题更清楚。

【问题讨论】:

  • 首先没有什么比geClassType()更好其次instanceof更好
  • @JigarJoshi 在我正在工作的程序的对象中
  • @AndreaF 你的意思是getClass().getName()
  • 呸。您应该避免编写这样的代码!不会通过我的代码审查。
  • instanceof Vs getClass( )的可能重复

标签: java


【解决方案1】:

instanceof 更高效,实际上可以工作(因为geClassType() 不存在)并且更具可读性。

如果 instanceof 是您想要的行为(正如其他答案指出的那样,您概述的两种方法之间的行为可能不同)我不确定您为什么还要考虑替代方案?

编辑:我应该重申,即使您的上下文中有一个方法可以执行您所描述的操作,我仍然看不出这样做的充分理由。如果它不能始终按照您期望的方式工作(例如在不同包中使用类似命名的类),它可能会引入错误,它可能会更慢,但更重要的是它是非标准的,因此会使您的代码可读性大大降低。

简而言之,instanceof 是一个有用的关键字,它可以准确地完成您想要的操作,可靠且易读,并且无需大惊小怪。你到底为什么不使用它?!

【讨论】:

  • @AndreaF 我已经相应地编辑了我的答案 - 我仍然看不到你不在这里使用 instanceof 的好案例。
  • 我不这么认为。请参考我的回答。
【解决方案2】:

您可能的意思是,使用 instanceof 验证对象引用是否属于特定类与比较类的名称有什么区别。

instanceof 适用于来自该类或被比较类的子类的对象引用。对于接口,如果对象引用的类(或超类)实现了该接口,则返回true

getClass().getName().equals("NameOfTheClass")(由您的getClassType 方法屏蔽)将验证对象引用的类是否完全来自另一个类,因此子类不会通过此测试。

使用哪一个?使用更适合您的情况的一种:

  • 如果您想要/需要使用属于某个类或接口的对象引用,即使该对象引用的类是子类或实现该接口,请使用instanceof。例如,当迭代 Collection 的元素以验证某些对象是否实现了所需的接口时。

  • 如果您需要确定对象引用的类是否完全特定类,请使用getClass().getName().equals("...")。例如,当在一个类中实现equals 方法时,该方法应与仅属于该类的元素进行比较(不允许子类)。一些 IDE 在自动生成 equals 方法时会这样做。

不过,比getClass().getName().equals("...") 更好的选择是getClass().equals(TheClass.class)


在效率方面,如果您只需要验证对象是否属于特定类,请使用getClass().equals(TheClass.class) 而不是getClass().getName().equals("..."),因为会比较引用(与instanceof 一样快)。但是,如果您只有类名,请使用您当前的方法。不要担心应用程序的性能,因为 JIT 会在多次执行代码后在运行时为您优化代码。不过,如果您认为此语句可能是性能瓶颈,请使用分析器证明它。

【讨论】:

  • 我认为instanceof 的行为是必需的,因为问题专门针对效率而不是功能 - 回想起来也许这个假设是不正确的!重读,老实说,我现在不太确定哪一种方法。
  • @berry120 在性能方面,你应该使用getClass().equals(TheClass.class) 而不是getClass().getName().equals("...") (但即使这是一个过早的优化,JIT 可能会为你踢出代码)。所以,真正的问题是:你需要比较什么,为什么?回答后,您可以选择首选选项。
  • 我对我的问题添加了另一个编辑。如果我理解了,在我的情况下应该是同一件事getClass().equals(TheClass.class)if(myObjec.geClassType().equals("Something"))。如果不。您能否提供更多细节来激发getClass().equals(TheClass.class) 优于if(myObjec.geClassType().equals("Something")) 的最佳性能?
【解决方案3】:

两者的工作方式可能不同,也可能不同。

if(myObjec instanceof Something){ 
}

如果myObjec 的类在运行时直接或间接是Something 或派生自Something 的任何类,则条件为true

if(myObjec.geClassType().equals("Something")){
}

如果geClassTypeSomething 中返回"Something" 的方法,并且它没有在任何子类中被覆盖,那么这等效于使用instanceof。但是,如果 Something 的任何子类覆盖 geClassType 以返回不同的字符串,则 instanceof 将为该类的对象返回 true,而第二个将返回 false

如果两者真的是等价的,我不知道哪一个会更有效,如果答案因一种实现而异,我也不会感到惊讶。

附:我同意这样的评论,即做其中任何一个都可能是错误的。相反,您应该考虑如何安排大括号内的逻辑以使其具有多态性;或者,如果您要测试的某些属性对于 Something 为 true,而对于其他类为 false,则添加多态 boolean isGrungy()boolean hasGrunginess() 方法以明确您要测试的内容, 而不是依赖类名。

【讨论】:

    【解决方案4】:

    你的意思可能是getClass

    instanceof 更好,因为

    • getClass 使用类名作为 String,这可能会拼错并且永远不会被发现(相等性检查将返回 false),
    • instanceOf 使用类本身
    • instanceof 的第二个参数在编译时检查,不仅检查类名,而且检查类层次结构(例如,“test” isanceof Integer 将得到编译时错误)。

    【讨论】:

    • getClass() 将调用已由类加载器存储的Class<ObjectClass> 的对象引用,它不会对性能造成任何影响,并且使用getClass().equals 进行比较与@987654331 一样快@ 操作员。可能您的意思是 getClass().getName() 有点慢(严重的是,0.0001 毫秒与 0.0005 毫秒不会使大型应用程序阻塞直到死机)。
    • @LuiggiMendoza 同意。性能方面可能根本没有区别。但总的来说instanceof 更好。
    • 这里没有比这更好的了。有一个你需要什么。有关更多信息,请参阅我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 2013-12-25
    • 1970-01-01
    • 2015-09-09
    相关资源
    最近更新 更多