类层次结构对java性能的影响有多大?

类层次结构对java性能的影响有多大?,java,performance,class-hierarchy,Java,Performance,Class Hierarchy,我有一个扩展了另一个类的类,它扩展了另一个类。。等等 100级层次结构的类的运行速度有多慢(以百分比表示),然后是10级层次结构的类?这将取决于您的JVM、您正在执行的确切操作、是否覆盖了各种方法等 然而,我更关心的是设计和可读性的影响,而不是性能的影响。这真的是你能想到的最好的设计吗?它解决了哪些无法用其他方法更好地解决的问题?根据Java2完整参考作者Herbert Schildr: 但是,您可以继承其中任何一个 类,Java类继承的级别 5岁以上的人不太值得注意。这 总是会降低性能 我也同

我有一个扩展了另一个类的类,它扩展了另一个类。。等等


100级层次结构的类的运行速度有多慢(以百分比表示),然后是10级层次结构的类?

这将取决于您的JVM、您正在执行的确切操作、是否覆盖了各种方法等


然而,我更关心的是设计和可读性的影响,而不是性能的影响。这真的是你能想到的最好的设计吗?它解决了哪些无法用其他方法更好地解决的问题?

根据Java2完整参考作者Herbert Schildr:

但是,您可以继承其中任何一个 类,Java类继承的级别 5岁以上的人不太值得注意。这 总是会降低性能

我也同意Jon Skeet的回答。

好的JVM(不管这意味着什么)缓存方法解析的结果。因此,性能影响应该只发生一次,甚至可能是最小的。然而,在对象创建时,每个扩展类的一个实例也将被创建,每个超类的每个构造函数都将被调用,这可能会在创建大量具有大型层次结构的对象时产生更大的影响

我必须同意Jon Skeet(当然,谁不同意)的观点,因为这个问题听起来像是有一些严重的设计问题,或者是一个代码生成器出了问题。这类似于询问“一个数据库表支持多少列”。如果它是非常合理的,那么你可能是做错了。

让我们试试:

class T1 {}
class T2 extends T1{}
class T3 extends T2{}
class T4 extends T3{}
class T5 extends T4{}
class T6 extends T5{}
class T7 extends T6{}
class T8 extends T7{}
class T9 extends T8{}
class T10 extends T9{}
class T11 extends T10{}
class T12 extends T11{}
class T13 extends T12{}
class T14 extends T13{}
class T15 extends T14{}
class T16 extends T15{}
class T17 extends T16{}
class T18 extends T17{}
class T19 extends T18{}
class T20 extends T19{}
class T21 extends T20{}
class T22 extends T21{}
class T23 extends T22{}
class T24 extends T23{}
class T25 extends T24{}
class T26 extends T25{}
class T27 extends T26{}
class T28 extends T27{}
class T29 extends T28{}
class T30 extends T29{}
class T31 extends T30{}
class T32 extends T31{}
class T33 extends T32{}
class T34 extends T33{}
class T35 extends T34{}
class T36 extends T35{}
class T37 extends T36{}
class T38 extends T37{}
class T39 extends T38{}
class T40 extends T39{}
class T41 extends T40{}
class T42 extends T41{}
class T43 extends T42{}
class T44 extends T43{}
class T45 extends T44{}
class T46 extends T45{}
class T47 extends T46{}
class T48 extends T47{}
class T49 extends T48{}
class T50 extends T49{}
class T51 extends T50{}
class T52 extends T51{}
class T53 extends T52{}
class T54 extends T53{}
class T55 extends T54{}
class T56 extends T55{}
class T57 extends T56{}
class T58 extends T57{}
class T59 extends T58{}
class T60 extends T59{}
我能够实例化T53,但T54之后抛出了StackOverflower错误

new T54();

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.ref.Reference.<init>(Reference.java:216)
    at java.lang.ref.FinalReference.<init>(FinalReference.java:16)
    at java.lang.ref.Finalizer.<init>(Finalizer.java:66)
    at java.lang.ref.Finalizer.register(Finalizer.java:72)
    at java.lang.Object.<init>(Object.java:20)
    at java.io.InputStream.<init>(InputStream.java:28)
    at java.io.FileInputStream.<init>(FileInputStream.java:96)
    at sun.misc.URLClassPath$FileLoader$1.getInputStream(URLClassPath.java:1005)
    at sun.misc.Resource.cachedInputStream(Resource.java:61)
    at sun.misc.Resource.getByteBuffer(Resource.java:144)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:256)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
newT54();
线程“main”java.lang.StackOverflowerr中出现异常
位于java.lang.ref.Reference。(Reference.java:216)
位于java.lang.ref.FinalReference(FinalReference.java:16)
位于java.lang.ref.Finalizer。(Finalizer.java:66)
位于java.lang.ref.Finalizer.register(Finalizer.java:72)
位于java.lang.Object。(Object.java:20)
在java.io.InputStream。(InputStream.java:28)
位于java.io.FileInputStream。(FileInputStream.java:96)
位于sun.misc.URLClassPath$FileLoader$1.getInputStream(URLClassPath.java:1005)
位于sun.misc.Resource.cachedInputStream(Resource.java:61)
位于sun.misc.Resource.getByteBuffer(Resource.java:144)
位于java.net.URLClassLoader.defineClass(URLClassLoader.java:256)
在java.net.URLClassLoader.access$000(URLClassLoader.java:58)
在java.net.URLClassLoader$1.run(URLClassLoader.java:197)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.net.URLClassLoader.findClass(URLClassLoader.java:190)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:307)
位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:248)
位于java.lang.ClassLoader.defineClass1(本机方法)
位于java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
位于java.lang.ClassLoader.defineClass(ClassLoader.java:616)
位于java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
位于java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
在java.net.URLClassLoader.access$000(URLClassLoader.java:58)
在java.net.URLClassLoader$1.run(URLClassLoader.java:197)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.net.URLClassLoader.findClass(URLClassLoader.java:190)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:307)
位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:248)
这是使用默认的JVM堆栈大小完成的


对于100级层次结构,您需要更大的堆栈。(您可以使用
Xss
增加堆栈大小)

我怀疑,如果您的应用程序具有100级的类层次结构,那么性能将是最不麻烦的问题。您真正的问题应该是“我的类层次结构有十几级甚至更深层次-我做错了什么,我如何改进我的设计?”我知道。我加入了Documentum定制的大项目,使用了大量java代码,对非常深的层次结构非常恼火。对于这个项目来说,20层的深度是典型的。不是真的-虽然可以执行超类构造函数代码,但是您只创建了一个新实例(超类构造函数在引擎盖下作用于派生类的实例)。很难想象每个构造函数都做了一些不能内联的事情。如果构造函数可以内联(在彼此内部),成本可能不会太大。@Peter:是的,JIT可以做到这一点。大概我对JIT的了解还不够。如果调用次数足够多(通常是10K时间),JIT将内联简单方法调用(包括构造函数),但是Andriod VM的行为可能会有所不同。;)您可能会在循环中首先伪造类加载:
for(String name:listOfClassNames)class.forName(name)。。。这不完全是一个可持续的解决方案