Function reference and function visibility


#1

I tried to use function references but again got problem. I have the code like this:

trait A {   val method : (() -> Unit )?   val test : Integer }

class AImpl : A {
  override val method : (() -> Unit )? = {
  println(“test2”)
  }
  override val test : Integer = Integer(777)
}

fun test(a : A) {
  val method = a.method
  if (method != null) {
  method()
  }
}

public fun main(args : Array<String>) {
  println(AImpl().test)
  test(AImpl())
}


But it fails at runtime:

Exception in thread “main” java.lang.IllegalAccessError: AImpl.getMethod()Ljet/Function0;


but prints 777 successfully

But if I modify AImpl method and add “public”

  public override val method : (() -> Unit )? = {
  println(“test2”)
  }


then everything will OK so it looks like method implementation is class private?

Is there something I missing?


#2

Default visibility is 'internal', so your example should work correctly. But visibility check is in progress now, so it doesn't tested properly yet.  Mind to file an issue about this to http://youtrack.jetbrains.com/issues/KT? Thanks


#3

svtk wrote: Default visibility is 'internal', so your example should work correctly.

Yes, it is but... the visiblity of variable is public but anonimous function used to initialize it probably not..


#4

There is no visibility for anonymous functions. Only members of packages and classes have visibility, and anonymous function cannot be a member (it's not by chance called 'anonymous':) ).


#5

I mean underlying implementation generated by compiler. I guess compiler generates private method for this anonimous function (only guess) or somthing like that. So I mean visibility checked by JVM, not visibility in terms of Kotlin.


#6

Ok, I understand what you mean. Thank you!


#7

You are right. It was haste to make guesses :) I can see the generated classes for my example. I can see getMethod() of AImpl isn't public and "anonimous" function is generated as separate class...

% javap A
Compiled from "cg.Test.kt"
public interface A extends jet.JetObject{
    public abstract jet.Function0 getMethod();
    public abstract java.lang.Integer getTest();
}

% javap AImpl
Compiled from "cg.Test.kt"
public final class AImpl extends java.lang.Object implements jet.JetObject,A{
  final jet.Function0 method;
  final java.lang.Integer test;
  jet.Function0 getMethod();
  java.lang.Integer getTest();
  public AImpl();
}

% javap AImpl$method$1
Compiled from "cg.Test.kt"
public class AImpl$method$1 extends jet.Function0{
  public java.lang.Object invoke();
  public final void invoke();
  public AImpl$method$1();
  public static AImpl$method$1 $getInstance();
}