0

In a android lib, having a public class in java which has default package level constructors

public class UserInformationException extends Exception {

    private static final String ERROR_MESSAGE = "User information wrong!!";

    UserInformationException(String msg) {
        super(msg);
    }

    UserInformationException() {
        super(ERROR_MESSAGE);
    }

This class is visible from other app (or outside the package), but the other part cannot create instance of it.

After converting this class into kotlin (using the internal modifier to restrict to visible only to this module is fine here)

class UserInformationException internal constructor(msg: String = ERROR_MESSAGE) : Exception(msg) {
    companion object {
        private const val ERROR_MESSAGE = "User information wrong!!"
    }
}

Looks like the kotlin internal constructor become public and be able to create the instance from it. The decompiled java code here:

public final class UserInformationException extends Exception {
   private static final String ERROR_MESSAGE = "User information wrong!!";
   @NotNull
   public static final UserInformationException.Companion Companion = new UserInformationException.Companion((DefaultConstructorMarker)null);

   public UserInformationException(@NotNull String msg) {
      Intrinsics.checkNotNullParameter(msg, "msg");
      super(msg);
   }

   // $FF: synthetic method
   public UserInformationException(String var1, int var2, DefaultConstructorMarker var3) {
      if ((var2 & 1) != 0) {
         var1 = "User information wrong!!";
      }

      this(var1);
   }

   public UserInformationException() {
      this((String)null, 1, (DefaultConstructorMarker)null);
   }

   public static final class Companion {
      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
   ... ...
}

Question: how to create class with (equivalent java package level visibility - the kotlin's internal to the module is fine) internal constructor only constructor?

14
  • 1
    There is no "package" accessibility modifier in kotlin. Commented Jun 7, 2022 at 15:12
  • I just brow the java word "package" here, but the internal modifier is ok if it restricts the constructor only visible to this module (not the outside world). The problem is that seems now the internal constructor become public to all. Commented Jun 7, 2022 at 15:19
  • Restricting access to only the module is exactly what internal does. Did you confuse "packages", which also exist in Kotlin, with "modules", which also exist in Java? Commented Jun 7, 2022 at 15:21
  • 1
    Java doesn't support such visibility. It just doesn't. You would have to use Java Modules. Commented Jun 7, 2022 at 15:34
  • 1
    It can, but only for the other Kotlin code. There is no way for the Kotlin compiler to produce a bytecode that the Java compiler will recognize as "internal". It just doesn't understand such visibility. internal is internal for Kotlin users and public for Java users. Commented Jun 7, 2022 at 15:40

1 Answer 1

2

You may simply do

data class MyPublicClass internal constructor(val property: String)

Every one can see it but only the current module can construct it.

Kotlin can not create package private visibility code. This is a language design choise. There are also no annotations available to tell the compiler wich visibiltiy should be choosen for this use case.

Sign up to request clarification or add additional context in comments.

3 Comments

cant use object here. and as @broot said for java client the internal does not work
In case this is a library, a java wrapper class may to the trick.
When you realy want to hide the constructor within kotlin, a private constructor would work when using reflection to create instances of that class. But this is more a hack than a solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.