ok i think i can successfully create instances of ...
# getting-started
s
ok i think i can successfully create instances of inner classes now, however this does not work if security manager is active
Copy code
class A {
    inner class B {
        inner class C {
            var empty: Int = 0
        }

        var empty: Int = 0
        var a: MutableList<C>

        init {
            a = mutableListOf(C())
        }
    }

    var a: MutableList<B>

    init {
        a = mutableListOf(B())
    }

    /**
     * test variable
     */
    var empty: Int = 0
}

fun getDeclaringUpperLevelClassObject(objectA: Any?): Any? {
    if (objectA == null) {
        return null
    }
    val cls = objectA.javaClass ?: return objectA
    val outerCls = cls.enclosingClass
        ?: // this is top-level class
        return objectA
    // get outer class object
    var outerObj: Any? = null
    try {
        val fields = cls.declaredFields
        for (field in fields) {
            if (field != null && field.type === outerCls
                && field.name != null && field.name.startsWith("this$")
            ) {
                /*
                `field.isAccessible = true` does not work with a Security Manager
                java.security.AccessControlException: access denied
                ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
                */
                field.isAccessible = true
                outerObj = field.get(objectA)
                break
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }

    return outerObj
}

/**
 * returns a [MutableList] of classes parenting the current class
 *
 * the top most class is always the last index
 *
 * the last class is always the first index
 *
 * for example: up(f[0].a[0].a[0]) = 0(f[0].a[0].a[0]) 1(f[0].a[0]) 2(f[0])
 */
fun up(a: Any, m: MutableList<Any> = mutableListOf(), debug: Boolean = false): MutableList<Any> {
    m.add(a)
    if (debug) println("get upper class of ${a.javaClass.name}")
    val upperC = getDeclaringUpperLevelClassObject(a)
    if (upperC == null) abort("upperC is null o.o")
    if (a.equals(upperC)) return m
    else {
        return up(upperC, m)
    }
}

/**
 * use as follows: `instanceChain(`[up]`(f[0]))`
 */
fun instanceChain(chain: MutableList<Any>, index: Int = chain.lastIndex, debug: Boolean = false): Any {
    return if (index == 0) {
        chain[index]
    } else {
        if (debug) println("chain[$index] = " + chain[index])
        val outer = chain[index]
        val toRun = Class.forName(chain[index].javaClass.name + "$" + chain[index - 1].javaClass.simpleName)
        val ctor = toRun.getDeclaredConstructor(chain[index]::class.java)
        val lowerCInstance = ctor.newInstance(outer)
        if (debug) println("lowerCInstance = " + lowerCInstance!!::class.java)
        if (index == 1) lowerCInstance
        else instanceChain(chain, index - 1)
    }
}

fun Test() {
    val f = mutableListOf<A>()
    f.add(A()) // this is required, i do not know how to do accomplish this in the init block
    println("f[0] = ${instanceChain(up(f[0]))}")
    println("f[0].a[0] = ${instanceChain(up(f[0].a[0]))}")
    println("f[0].a[0].a[0] = ${instanceChain(up(f[0].a[0].a[0]))}")
    abort()
}
🤢 2
s
What if the passed value doesn’t have an inner class? What if it has an inner class that has a private constructor? What if it has an inner class that doesn’t have a noarg constructor? This approach only works in a very limited set of cases if you already know that the above conditions are false.
s
"What if the passed value doesn’t have an inner class" isnt that handled by f[0] since that is of type outer most class (class A)? "What if it has an inner class that has a private constructor" "What if it has an inner class that doesn’t have a noarg constructor" could you provide examples of those?
as i would like to try to make this able to work for all possible cases that it can work for
s
Why?
s
so it is not limited to a "very limited set of cases"?
s
No, I’m asking why do you need a function that does this. It’s a hacked-together solution for a problem that doesn’t need to be solved. So why are you making this function? What is your use case?
s
dunno lol
cus why not for no reason at all? xP
s
Well for starters, the code you provided doesn’t actually work, at least not on pl.kotl.in
s
o.o
s
Just don’t use this in production, for the love of Kotlin. Stick to what the language is built for
s
your right, i keep getting
Expression in a class literal has a nullable type 'E', use !! to make the type non-nullable
no matter what i do, in kotlin playground
i worked around the first problem, but apparently
::class.isInner
refuses to be called, with
Copy code
Exception in thread "main" java.lang.IllegalStateException: No BuiltInsLoader implementation was found. Please ensure that the META-INF/services/ is not stripped from your application and that the Java virtual machine is not running under a security manager
if i put the class inside
main
i get
Copy code
Exception in thread "main" java.security.AccessControlException: Access control exception due to security reasons in web playground: 
 access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
https://pl.kotl.in/SkzV6ssK4
for
Copy code
fun main(args: Array<String>) {
    class A() {}
    println(A::class.isInner)
}
s
Well, guess we have an additional case where it doesn’t work; when the security manager of the JVM is locked down
s
and
field.isAccessible = true
is not allowed either in web playground