-3

What's the Java equivalent of this Kotlin declaration?

var doOnAppCouldNotBeFrozen: ((Context) -> Unit)? = null

I think this is a "function type" but I'm not sure. Is it a method or a variable? I know that Unit means void so then is it a method that returns void?

The only way I can understand what it means is if I can see how it's written in Java (without the question mark after Unit).

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 2
    It's the definition of a variable, holding a lambda of type `(Context) -> Unit` (a function that takes in a `Context` and returns a `Unit`), and it is nullable. – Turing85 Apr 03 '21 at 14:46
  • Well then maybe if your experience is all your questions getting downvoted, you should read [ask]? I think the comment from @Turing85 explains it perfectly. – Henry Twist Apr 03 '21 at 14:49
  • There is no 1:1 relation since Java has no concept of non-nullableness. If we ignore this, the equivalent would be `Function doOnAppCouldNotBeFrozen = null;` or `Consumer doOnAppCouldNotBeFrozen = null;` – Turing85 Apr 03 '21 at 14:49
  • @Turing85 I'm confused now. Is it a variable or a function? I've never seen that kind of statement in java before – Farou Faroud Apr 03 '21 at 14:54
  • 2
    It is a variable. If you have never seen the concept, I recommend reading a tutorial on lambdas, e.g. [this one by oracle](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html), as well as the [documentation of the `java.util.function`-package](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/function/package-summary.html). – Turing85 Apr 03 '21 at 14:55
  • I didn't make my suggestion to prevent you from getting downvoted. I made the suggestion because if this question is to be useful for future readers than they must be able to find it and your original title is not really searchable. – takendarkk Apr 03 '21 at 14:57
  • @FarouFaroud *"Is it a variable or a function?"* It's kind of a variable *to* a function. – Andreas Apr 03 '21 at 15:02
  • @Andreas Functions are not first-class citizens in Java. It is actually a variable holding a reference to a concrete interface-implementation. This may or may not be a lambda expression or a method reference, both of which, as far as I know, get compiled-down to an anonymous interface implementations. – Turing85 Apr 03 '21 at 15:05
  • @Turing85 "Kind of" means "not really, but abstractly it behaves very close to that". --- And no, lambdas and method references never become anonymous classes. A lambda becomes a hidden (synthetic) method and is then a method reference to that hidden method. – Andreas Apr 03 '21 at 15:25
  • @Turing85 in Android studio trying to use the `accept` or `apply` methods after defining those interfaces always says they require min API 24 – Farou Faroud Apr 03 '21 at 16:17
  • @FarouFaroud Lambdas and the `java.util.function`-package were introduced in Java 8. – Turing85 Apr 03 '21 at 16:24
  • @Turing85 So what to do if I target lower APIs? – Farou Faroud Apr 03 '21 at 16:25
  • @FarouFaroud Please read: [Can I ask only one question per post?](https://meta.stackexchange.com/questions/222735/can-i-ask-only-one-question-per-post) – Turing85 Apr 03 '21 at 16:26
  • @Turing85 To be pedantic, a lambda isn’t a type of object. It is one of many possible syntaxes used to define a function. The variable here is not of a lambda type. You could assign any function with matching type, not just ones defined by lambdas. – Tenfour04 Apr 03 '21 at 20:57
  • @Tenfour04 For Kotlin, I take you word for it :) (I am not as firm in Kotlin's spec as I am in Java's). For Java, the last information I had was that lambdas are "just" syntactic sugar for anonymous interface implementations. – Turing85 Apr 03 '21 at 21:58

2 Answers2

2

The java equivalent of the kotlin code is:

Consumer<Context> doOnAppCouldNotBeFrozen = null;

If you want to learn more about the Consumer, I can recommend the documentation.

EDIT: Using the java stream below api 24 requires desugaring to be enabled:

If you're building your app using Android Gradle plugin 4.0.0 or higher, the plugin extends support for using a number of Java 8 language APIs without requiring a minimum API level for your app.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
flaxel
  • 4,173
  • 4
  • 17
  • 30
  • Ok so I have to use `doOnAppCouldNotBeFrozen.accept(context)` to use it later? Android Studio says the accept() method requires API 24 – Farou Faroud Apr 03 '21 at 16:11
  • Yes that is correct. And I found [this post](https://stackoverflow.com/questions/39515035/is-it-possible-to-use-the-java-8-stream-api-on-android-api-24). So it is not possible to use the java stream below api 24. – flaxel Apr 03 '21 at 16:27
-2

To get Java equivalent of every Kotlin code

Select Tools > Kotlin > Show Kotlin Bytecode

Screenshot 2021-04-03 at 15 01 49

Then click DECOMPILE

Screenshot 2021-04-03 at 15 08 03

This is Java equivalent in Android Studio

   @Nullable
   private static Function1 doOnAppCouldNotBeFrozen;

   @Nullable
   public static final Function1 getDoOnAppCouldNotBeFrozen() {
      return doOnAppCouldNotBeFrozen;
   }

   public static final void setDoOnAppCouldNotBeFrozen(@Nullable Function1 var0) {
      doOnAppCouldNotBeFrozen = var0;
   }
Kakyire
  • 112
  • 6
  • 1
    You may want to mention which IDE you are using. – Turing85 Apr 03 '21 at 15:10
  • I am using Android Studio – Kakyire Apr 03 '21 at 15:11
  • 2
    Maybe you want to [edit] your answer and include this information? – Turing85 Apr 03 '21 at 15:12
  • While we are on the topic: You may want to include the definition of `Function1` aswell. – Turing85 Apr 03 '21 at 15:15
  • The `Function1` was generated by the IDE – Kakyire Apr 03 '21 at 15:23
  • I doubt that. If it appears in the bytecode, it should have been generated by the compiler. Anyway, the definition of `Function1` is where the actual magic happens. – Turing85 Apr 03 '21 at 15:24
  • Actually the ``Function1`` is the `Type`. – Kakyire Apr 03 '21 at 15:25
  • 1
    @Turing85 `Function1` is likely a (static) nested interface generated by Kotlin. Since it is a different type, the UI likely didn't show it, it only showed the bytecode of the main type in the source file. Limit of the IDE. – Andreas Apr 03 '21 at 15:34
  • @KakyireLastBorn yes, but the type needs an implementation, that is where the "mapping" from the kotlin-syntax to the JVM-code (an, in last instance, the Java-code) happens. – Turing85 Apr 03 '21 at 15:54
  • @Andreas I know. But the definition of `Function1` is what reveals the "mapping" from the kotlin-syntax to the JVM-code. – Turing85 Apr 03 '21 at 15:56