Note that there are some explanatory texts on larger screens.

plurals
  1. POIssue with constructors of nested class
    primarykey
    data
    text
    <hr> <blockquote> <p>This question is about interesting behavior of Java: it produces additional (not default) constructor for nested classes in some situations.</p> <p>This question is also about strange anonymous class, which Java produces with that strange constructor.</p> </blockquote> <hr> <p>Consider the following code:</p> <pre><code>package a; import java.lang.reflect.Constructor; public class TestNested { class A { A() { } A(int a) { } } public static void main(String[] args) { Class&lt;A&gt; aClass = A.class; for (Constructor c : aClass.getDeclaredConstructors()) { System.out.println(c); } } } </code></pre> <p>This will prints:</p> <pre><code>a.TestNested$A(a.TestNested) a.TestNested$A(a.TestNested,int) </code></pre> <p>Ok. Next, lets make constructor <code>A(int a)</code> private:</p> <pre><code> private A(int a) { } </code></pre> <p>Run program again. Receive:</p> <pre><code>a.TestNested$A(a.TestNested) private a.TestNested$A(a.TestNested,int) </code></pre> <p>It is also ok. But now, lets modify <code>main()</code> method in such way (addition of new instance of class <code>A</code> creation):</p> <pre><code>public static void main(String[] args) { Class&lt;A&gt; aClass = A.class; for (Constructor c : aClass.getDeclaredConstructors()) { System.out.println(c); } A a = new TestNested().new A(123); // new line of code } </code></pre> <p>Then input becomes:</p> <pre><code>a.TestNested$A(a.TestNested) private a.TestNested$A(a.TestNested,int) a.TestNested$A(a.TestNested,int,a.TestNested$1) </code></pre> <p>What is it: <strong>a.TestNested$A(a.TestNested,int,a.TestNested$1)</strong> &lt;&lt;&lt;---??</p> <p>Ok, lets again make constructor <code>A(int a)</code> package local:</p> <pre><code> A(int a) { } </code></pre> <p>Rerun program again (we <strong>don't remove</strong> line with instance of <code>A</code> creation!), output is as in the first time:</p> <pre><code>a.TestNested$A(a.TestNested) a.TestNested$A(a.TestNested,int) </code></pre> <hr> <p><strong>Questions:</strong></p> <p><strong>1)</strong> How this could be explained?</p> <p><strong>2)</strong> What is this third strange constructor?</p> <hr> <p><strong>UPDATE:</strong> Investigation shown following.</p> <p>1) Lets try to call this strange constructor using reflection from other class. We will not able to do this, because there isn't any way to create instance of that strange <code>TestNested$1</code> class.</p> <p>2) Ok. Lets do the trick. Lets add to the class <code>TestNested</code> such static field:</p> <pre><code>public static Object object = new Object() { public void print() { System.out.println("sss"); } }; </code></pre> <p>Well? Ok, now we could call this third strange constructor from another class:</p> <pre><code> TestNested tn = new TestNested(); TestNested.A a = (TestNested.A)TestNested.A.class.getDeclaredConstructors()[2].newInstance(tn, 123, TestNested.object); </code></pre> <p>Sorry, but I absolutely don't understand it.</p> <hr> <p><strong>UPDATE-2:</strong> Further questions are:</p> <p><strong>3)</strong> Why Java use special anonymous inner class for an argument type for this third synthetic constructor? Why not just <code>Object</code> type, of constructor with special name?</p> <p><strong>4)</strong> What Java could use already defined anonymous inner class for those purposes? Isn't this some kind of violation of security?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

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