Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Take this class for example:</p> <pre><code>public class Tmp { public static void main(String[] args) { ArrayList&lt;Integer&gt; numbers = new ArrayList&lt;Integer&gt;(); numbers.add(1); } } </code></pre> <p>It compiles down to this:</p> <pre><code>Compiled from "Tmp.java" public class Tmp extends java.lang.Object{ public Tmp(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."&lt;init&gt;":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2; //class java/util/ArrayList 3: dup 4: invokespecial #3; //Method java/util/ArrayList."&lt;init&gt;":()V 7: astore_1 8: aload_1 9: iconst_1 10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 13: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;)Z 16: pop 17: return } </code></pre> <p>While this class:</p> <pre><code>public class Tmp { public static void main(String[] args) { List&lt;Integer&gt; numbers = new ArrayList&lt;Integer&gt;(); numbers.add(1); } } </code></pre> <p>compiles down to this:</p> <pre><code>Compiled from "Tmp.java" public class Tmp extends java.lang.Object{ public Tmp(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."&lt;init&gt;":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2; //class java/util/ArrayList 3: dup 4: invokespecial #3; //Method java/util/ArrayList."&lt;init&gt;":()V 7: astore_1 8: aload_1 9: iconst_1 10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 13: invokeinterface #5, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 18: pop 19: return } </code></pre> <p>You'll see that the only difference is the first one (using an <code>ArrayList</code>) makes a call to <code>invokevirtual</code> and the other one (using <code>List</code> uses) <code>invokeinterface</code>. <code>invokeinterface</code> is actually a hair slower than <code>invokevirtual</code> (~38% according to <a href="http://bobah.net/d4d/source-code/misc/invokevirtual-vs-invokeinterface-performance-benchmark" rel="nofollow noreferrer">this guy</a>). This is <a href="https://stackoverflow.com/a/1505476/836738">apparently</a> due to optimizations the JVM can make when searching through a concrete class's virtual method tables versus an interface's method tables. So what you're saying is actually true. Interface invocations <em>are</em> slower than concrete class invocations.</p> <p>However, you have to consider what sorts of speed we're talking about. For 100,000,000 invocations, the actual difference was .03 seconds. So you have to have a <em>ton</em> of invocations to actually have a significant decrease in speed.</p> <p><strike>On the other hand, as @ChinBoon points out, coding to an interface makes it significantly easier for those using your code, especially if your code returns some sort <code>List</code>. So in the <em>vast</em> majority of cases, the ease of coding <em>far</em> outweighs the relative performance expense.</strike></p> <hr> <p><sup>Added after reading @MattQuigley's comment and giving it a think on the drive home</sup></p> <p>What all this means is that this isn't something you should worry about too much. Any performance gain or penalty is likely to be <em>very</em> small.</p> <p>Keep in mind, using the interface for your return types and your parameters on methods is a Very Good Idea. That allows you and anybody who uses your code to use whatever implementation of <code>List</code> best suits their needs. My example also shows that, if you happen to use a method that returns <code>List</code>, 99% of the time, you are <em>not</em> better off casting it to a concrete class just to get a performance boost. The time it takes to cast will likely outweigh the gain in performance.</p> <p>That being said, this example also shows that, for a <em>local</em> variable, you are indeed better off using a concrete class rather than an interface. If the only methods you use are methods on <code>List</code>, then you can switch out implementing classes with no side effects. Plus you would have access to the implementation specific methods should you need them. Plus there is a minor performance boost.</p> <p><strong><em>tl;dr</em></strong></p> <p>Always use interfaces for return types and parameters on methods. It's a good idea to use concrete classes for local variables. It gives minor performance gains and there is no cost to switching implementations if the only methods you use are on the interface. In the end, you shouldn't worry about it too much. (Except the return types and parameters thing. That's important.)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload