Kotlin protected static function behaves differently as in Java

Sorry if this has already been posted.

Consider this Java code:

public class A {

    protected int number;

    public A(int number) {
        this.number = number;
    }
}

public class B extends A{

    private B(int number) {
        super(number);
    }

    public static B createFromA(A a) {
        return new B(a.number);
    }

}

Kotlin equivalent would be:

open class A(protected val number: Int)


class B private constructor(number: Int) : A(number) {

    companion object {
        @JvmStatic
        fun createFromA(a: A) = B(a.number)
        
    }
}

Though a.number is not visible from the static function.

Could anyone please help me how I could work around that fields with protected visibility are not visible from inheritors’ static function? Thank you in advance.

The only thing that I can think of is making public pseudo-getter:

open class A(protected val number: Int) {
	fun number() = number
}


class B private constructor(number: Int) : A(number) {

	companion object {
		@JvmStatic
		fun createFromA(a: A) = B(a.number())

	}
}

I think I’ve found a slightly more elegant example than making it public. However, this seems very hacky and unintended by design.

open class A(protected val number: Int) {

    companion object {

        @JvmStatic
        protected val A._number
            get() = number
    }
}

class B private constructor(number: Int) : A(number) {

    companion object {
        @JvmStatic
        fun createFromA(a: A) = B(a._number)

    }
}

Could someone please shed some light on what the difference between Java-protected and Kotlin-protected visbility is?

Java protected means that it’s not only protected (that is children can access) but also package local.
In kotlin, protected really means only children can access.

1 Like