How to access outer class instance variables from inner class in controller?

If you want your inner class to access outer class instance variables then in the constructor for the inner class, include an argument that is a reference to the outer class instance.

The outer class invokes the inner class constructor passing this as that argument.

public class OuterClass {
  String instanceVbl;


  public void myOuterMethod() {
    InnerClass ic = new InnerClass(this);
    ic.someInnerMethod();
  }
  public class InnerClass {
    OuterClass outer;
    public InnerClass (OuterClass outer) {
       this.outer = outer;
    }
    public void someInnerMethod() {
      String s = outer.instanceVbl + 'appendedStringBits';
      // do something more useful
    }

The example is artificial but illustrates how this can be used to give the Inner Class access to anything the Outer Class instance can reference.


There is no direct access to outer classes, but you can use a reference (I do this fairly extensively). The pattern looks like:

public class someController {
    public class wrapper {
        someController controller;
        public wrapper(someController con) {
            controller = con;
        }
        public void remove() {
            controller.remove(this);
        }
    }
    public void remove(wrapper item) {
        for(integer i = 0; i < items.size(); i++) {
            if(items[i] == item) {
                items.remove(i);
                break;
            }
        }
    }
    public void add() {
        items.add(new wrapper(this));
    }
    public someController() {
        items = new wrapper[0];
    }
    public wrapper[] items { get; set; }
}

This is a fully functional controller where wrapper can reference someController; it uses that reference to remove itself from a list via a function. Conversely, someController can iterate through items in order to find the relevant instance of a wrapper. It can also access members of the inner class.

Because you can't reference outer classes directly, this method enables your inner classes to communicate with your outer classes.


Inner classes in Apex are static inner classes so they cannot have references to instance variables of their outer classes which you have observed. There are no non-static inner classes in Apex like there are in some other languages like Java.

You are accessing the static variable of the outer class correctly, but the initialization that you think is happening in the constructor is not.

The reason for str1 not being initialized is that The inner class is not a subclass of the outer class, so the outer class constructor will not run when an instance of the inner class is created, and therefore, str1 will be null. If you want to initialize it you can use a static initializer block.

public static String str1;

static {
    str1 = 'string1';
}

Or just assign it directly:

public static String str1 = 'string1';

See the Static and Instance documentation in the Apex Code Developer's Guide for more information.