Two declared constructors in inner class

I have a public class with a private class inside it:

public class A {

   private class B
   {
   }

   private final B b = new B();

   public static void main(String[] args) {
       Class<?> bClass = A.class.getDeclaredClasses()[0];
       Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
       System.out.println(declaredConstructors.length);  //result = 2
   }
}

The problem is, that the declared constructors in class B equals two.

Although in other cases, the number of constructors in class B equals one:

public class A {

   private class B
   {
       public B()
       {
       }
   }

   private final B b = new B();

   public static void main(String[] args) {
       Class<?> bClass = A.class.getDeclaredClasses()[0];
       Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
       System.out.println(declaredConstructors.length);  //result = 1
   }
}

and

public class A {

   private class B
   {
   }

   public static void main(String[] args) {
       Class<?> bClass = A.class.getDeclaredClasses()[0];
       Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
       System.out.println(declaredConstructors.length);  //result = 1
   }
}

The question is why in the first case 2 constructors?
Thanks!

Solution:

As already shortly mentioned by chrylis what you are seeing here is a synthetic constructor.

Basically, whenever you access private attributes of a nested class from the nesting class the compiler needs to create a synthetic method for this access.

In your first example the default constructor is private so when you call it a synthetic method is created (thus “2” constructors exist).

In your second example the constructor is declared as public and no such issue exists.

In your third example once again it is private but also never accessed so there is no need to create a synthetic method.

If you are interested in more detail, read into Chapter 13.1.7 of the Java Language Specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html) where it is explained a bit further.

Also if you are interested in the implications of synthetic method this post might be interesting to you, discussing the implications of them in regards to security (and performance): What's the penalty for Synthetic methods?

Also, if you want to read more into the inner workings of this concept, I can recommend the following article: https://www.javaworld.com/article/2073578/java-s-synthetic-methods.html (which (to my knowledge) should still be up to date)

Java reflection to set static final field fails after previous reflection

In Java, it turns out that field accessors get cached, and using accessors has side-effects. For example:

class A {
    private static final int FOO = 5;
}

Field f = A.class.getDeclaredField("FOO");
f.setAccessible(true);
f.getInt(null); // succeeds

Field mf = Field.class.getDeclaredField("modifiers" );
mf.setAccessible(true);

f = A.class.getDeclaredField("FOO");
f.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.setInt(null, 6); // fails

whereas

class A {
    private static final int FOO = 5;
}

Field mf = Field.class.getDeclaredField("modifiers" );
mf.setAccessible(true);

f = A.class.getDeclaredField("FOO");
f.setAccessible(true);
mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.setInt(null, 6); // succeeds

Here’s the relevant bit of the stack trace for the failure:

java.lang.IllegalAccessException: Can not set static final int field A.FOO to (int)6
    at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
    at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:100)
    at sun.reflect.UnsafeQualifiedStaticIntegerFieldAccessorImpl.setInt(UnsafeQualifiedStaticIntegerFieldAccessorImpl.java:129)
    at java.lang.reflect.Field.setInt(Field.java:949)

These two reflective accesses are of course happening in very different parts of my code base, and I don’t really want to change the first to fix the second. Is there any way to change the second reflective access to ensure it succeeds in both cases?

I tried looking at the Field object, and it doesn’t have any methods that seem like they would help. In the debugger, I noticed overrideFieldAccessor is set on the second Field returned in the first example and doesn’t see the changes to the modifiers. I’m not sure what to do about it, though.

If it makes a difference, I’m using openjdk-8.

Solution:

If you want the modifier hack (don’t forget it is a total hack) to work, you need to change the modifiers private field before the first time you access the field.

So, before you do f.getInt(null);, you need to do:

mf.setInt(f, f.getModifiers() & ~Modifier.FINAL);

The reason is that only one internal FieldAccessor object is created for each field of a class (*), no matter how many different actual java.lang.reflect.Field objects you have. And the check for the final modifier is done once when it constructs the FieldAccessor implementation in the UnsafeFieldAccessorFactory.

When it is determined you can’t access final static fields (because, the setAccessible override doesn’t works but non-static final fields, but not for static final fields), it will keep failing for every subsequent reflection, even through a different Field object, because it keeps using the same FieldAccessor.

(*) barring synchronization issues; as the source code for Field mentions in a comment:

// NOTE that there is no synchronization used here. It is correct
(though not efficient) to generate more than one FieldAccessor for a
given Field.

Java Reflection – IllegalAccessException on "set" if preceded by "get" operation

I was trying to change the value of a private static final field using reflection (yes, that’s probably a very bad idea to begin with, I know).
And, well, for the most part it works fine using following code:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class A {

    public static void main(String[] args) throws ReflectiveOperationException {
        System.out.println("Before :: " + B.get());
        Field field = B.class.getDeclaredField("arr");
        field.setAccessible(true);
        // System.out.println("Peek   :: " + ((String[]) field.get(null))[0]);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, new String[] { "Good bye, World!" });
        System.out.println("After  :: " + B.get());
    }
}

class B {
    private static final String[] arr = new String[] { "Hello, World!" };

    public static String get() {
        return arr[0];
    }
}

Which prints as expected:

Before :: Hello, World!
After  :: Good bye, World!

Problems arise when I try to get the field value via reflection prior to setting it.
That is, if I uncomment the commented line in above sample, I get the following:

Before :: Hello, World!
Peek   :: Hello, World!
Exception in thread "main" java.lang.IllegalAccessException: Can not set static final [Ljava.lang.String; field B.arr to [Ljava.lang.String;
        at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:76)
        at sun.reflect.UnsafeFieldAccessorImpl.throwFinalFieldIllegalAccessException(UnsafeFieldAccessorImpl.java:80)
        at sun.reflect.UnsafeQualifiedStaticObjectFieldAccessorImpl.set(UnsafeQualifiedStaticObjectFieldAccessorImpl.java:77)
        at java.lang.reflect.Field.set(Field.java:764)
        at A.main(A.java:14)

Why is this happening??
I tried to set again the accessible flag after the call to get but it doesn’t help.
I tried many other things that don’t seem to help either…

Thanks for your help!


Edit: there is an element of answer in Using reflection to change static final File.separatorChar for unit testing? (see “Important update” by @Rogério).

Important update: the above solution does not work in all cases. If the field is made accessible and read through Reflection before it gets reset, an IllegalAccessException is thrown. It fails because the Reflection API creates internal FieldAccessor objects which are cached and reused (see the java.lang.reflect.Field#acquireFieldAccessor(boolean) implementation).
Example test code which fails:

Field f = File.class.getField("separatorChar"); f.setAccessible(true); f.get(null);
// call setFinalStatic as before: throws IllegalAccessException

Sadly, it doesn’t say anything about how to work around it… How do I “reset” the field?

Solution:

A very bad idea, indeed.

I’m not sure how deeply one should go into details when answering this question. But here’s a short summary of what happens:

When you do the reflective Field#get call, the the call will internally (after a few security checks) be delegated to a sun.reflect.FieldAccessor. This is an internal interface that, as the name suggests, provides access to field values. The FieldAccessor instance that is used internally is created lazily, “cached” for later use, and even shared among multiple Field instances.

There are many different implementations of the FieldAccessor interface. These implementations are specialized for the various cases of normal Fields, static Fields, or private Fields that have been made accessible by calling setAccessible(true). For example, in your case, there is a UnsafeQualifiedStaticObjectFieldAccessorImpl involved, and the name already suggests that this is only one of a few dozen specializations.

Many of these FieldAccessor implementations store an internal state, which describe some properties of the field. For example, whether the field is “read only” or final (!).

The point is: The FieldAccessor that is created when you do the reflective Field#get call is the same that will later be used for the reflective Field#set call. But when the FieldAccessor is created, the field is still considered to be final. You are changing this only after you created the FieldAccessor.

So the easiest solution is to make sure that the final-status of the field is changed before you do this first reflective call. This way, the FieldAccessor that is created internally is one that operates on a “non-final” field:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class A {

    public static void main(String[] args) throws Exception {
        System.out.println("Before :: " + B.get());
        Field field = B.class.getDeclaredField("arr");
        field.setAccessible(true);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        System.out.println("Peek   :: " + ((String[]) field.get(null))[0]);
        field.set(null, new String[] { "Good bye, World!" });
        System.out.println("After  :: " + B.get());
    }
}

class B {
    private static final String[] arr = new String[] { "Hello, World!" };

    public static String get() {
        return arr[0];
    }
}

I should not mention this. People will do this. But however:

Technically, it is also possible to brutallyHackYourWayThroughInternalClasses and modify the FieldAccessor that was created internally, so that it afterwards allows modifying the field, even though it initially was created for the final version of the field:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class A {

    public static void main(String[] args) throws Exception {
        System.out.println("Before :: " + B.get());
        Field field = B.class.getDeclaredField("arr");
        field.setAccessible(true);

        System.out.println("Peek   :: " + ((String[]) field.get(null))[0]);
        brutallyHackYourWayThroughInternalClasses(field);

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        field.set(null, new String[] { "Good bye, World!" });
        System.out.println("After  :: " + B.get());
    }

    private static void brutallyHackYourWayThroughInternalClasses(Field field)
        throws Exception
    {
        Field overrideFieldAccessorField = 
            Field.class.getDeclaredField("overrideFieldAccessor");
        overrideFieldAccessorField.setAccessible(true);
        Object overrideFieldAccessorValue = 
            overrideFieldAccessorField.get(field);

        Class<?> unsafeFieldAccessorImplClass = 
            Class.forName("sun.reflect.UnsafeFieldAccessorImpl");
        Field isFinalField = 
            unsafeFieldAccessorImplClass.getDeclaredField("isFinal");
        isFinalField.setAccessible(true);
        isFinalField.set(overrideFieldAccessorValue, false);

        Class<?> unsafeQualifiedStaticFieldAccessorImplClass = 
            Class.forName("sun.reflect.UnsafeQualifiedStaticFieldAccessorImpl");
        Field isReadOnlyField = 
            unsafeQualifiedStaticFieldAccessorImplClass.getDeclaredField(
                "isReadOnly");
        isReadOnlyField.setAccessible(true);
        isReadOnlyField.set(overrideFieldAccessorValue, false);
    }
}

class B {
    private static final String[] arr = new String[] { "Hello, World!" };

    public static String get() {
        return arr[0];
    }
}