Comparing two classes by its types or class names

前端 未结 7 1081
耶瑟儿~
耶瑟儿~ 2021-02-01 15:34

There is need to compare two objects based on class they implement? When to compare using getClass() and when getClass().getName()? Is there any differ

相关标签:
7条回答
  • 2021-02-01 15:40

    Is there any difference between this approaches to compare two Objects class types (names)?

    Yes. Two classes may have the same name if they are loaded by different ClassLoaders.

    "The basics of Java class loaders" says

    At its simplest, a class loader creates a flat name space of class bodies that are referenced by a string name.

    "Eclipse - a tale of two VMs (and many classloaders)" says

    That means it's possible to have two classes with the same name loaded into a VM at once, provided that they have two separate ClassLoaders


    When to compare using getClass() and when getClass().getName()?

    If you want to know whether two objects are of the same type you should use the equals method to compare the two classes -- the first option.

    I can't imagine why you'd want to do this, but if you want to know whether two objects with different concrete types have types with the same fully qualified name, then you could use the second. If you don't understand "concrete types" and "fully qualified names" in the context of Java then you're not writing type analysis code for java so you don't want to.

    0 讨论(0)
  • 2021-02-01 15:40

    As a matter of fact comparing trusted class by name is a weakness. Refer https://cwe.mitre.org/data/definitions/486.html

    if (nextMonster.getClass() == monster.getClass())
    

    is the correct way to compare classes

    if (nextMonster.getClass().equals(monster.getClass()))
    

    should still work for the same reason @Bohemian mentioned

    0 讨论(0)
  • 2021-02-01 15:40

    You can use the inbuilt method of Class :

    if(nextMonster.getClass().isAssignableFrom(monster.getClass()))
    
    0 讨论(0)
  • 2021-02-01 15:43

    I ran into a problem comparing two classes using .equals. The above provided solution is not entirely accurate. Class does not implement Comparable.

    Class references are not necessarily true singletons within a JVM because you can have multiple ClassLoaders.

    I was writing a Maven plugin that was digging annotations out of beans after compile. The plugin had one classloader and I had my own classloader. When comparing two classes of the same name from different loaders the comparison would fail.

    The implementation of Object.equals looks like this:

    public boolean More ...equals(Object obj) {
           return (this == obj);
    }
    

    So you will be comparing references.

    If you are comparing classes and you know for sure there will only be one classloader involved you can safely use .equals or c1 == c2 but if you are not sure you should compare by name:

    if(c1.getName().equals(c2.getName()) {
       ...
    }
    
    0 讨论(0)
  • 2021-02-01 15:53

    if you have an array to compare then use below

    array.getClass().getComponentType() == X.class
    
    0 讨论(0)
  • 2021-02-01 16:01

    Use class.equals():

    if (nextMonster.getClass().equals(monster.getClass()))
    

    or, because each class is like a singleton - there's only one instance of each Class per class loader, and most JVMs only have the one class loader - you can even use an identity comparison:

    if (nextMonster.getClass() == monster.getClass())
    
    0 讨论(0)
提交回复
热议问题