5
votes

I am trying to create a nested inner class in Kotlin with a companion object factory method (the equivalent of a static factory method in Java). Here's a simplified version of my code.

class OuterClass {

    var myData:List<MyData> = List<>() //gets populated elsewhere

    fun getItemFragment(position:Int) : Fragment() {
        return InnerClass.Factory.newInstance(position)
    }

    inner class InnerClass : Fragment() {

        companion object Factory {

            fun newInstance(position:Int) : InnerClass {
                var ic : InnerClass = InnerClass()
                var bundle:Bundle = Bundle()
                bundle.putInt("index", position)
                ic.arguments = bundle
                return ic
            }

        }

        override fun onCreateView(inflater:LayoutInflater, container: ViewGroup, savedInstanceState:Bundle): View? {
            //create and return view, omitted. Need access to myData
    }
}

The compilier highlights "companion", saying "Modifier companion is not applicable inside inner class" and it also highlights the InnerClass() call, saying "Expression is inaccessible from a nested class Factory", use "inner" keyword to make the class inner.

How can I achieve what I'm trying to do here with the equivalent of a static factory method in Java?

1
You should never make a Fragment an inner class because it needs a zero-args constructor. More on that topic: stackoverflow.com/questions/15571010/…Kirill Rakhman

1 Answers

15
votes

You can have:

class OuterClass {
    fun getItemFragment(position: Int): Fragment {
        return InnerClass.Factory.newInstance(position)
    }

    class InnerClass : Fragment() {
        companion object Factory {
            fun newInstance(position: Int): InnerClass {
                var ic: InnerClass = InnerClass()
                return ic
            }
        }
    }
}

However the following will not compile in Kotlin:

class Parent {
    inner class Nested {
        companion object Factory { 
        }
    }
}

For the same reasons the following will not compile in Java:

public class Parent {
    public class Nested {
        public static boolean create(){
            return false;
        }
    }
}

The culprit here is that nested inner classes in Kotlin, as well as nested non static classes in Java have an implicit reference to parent class instance. Since Kotlin aims to be highly interoperable with Java it follows the same rule.

Please see following questions for more in-depth explanation: