I had seen forums and questions that can be used kotlin in java but, with respect to my question is that I want to use the apache math commons library ("which is only available in java") within kotlin. My project is in intellij idea and I have imported the library correctly, I show you how it is written in java
import org.apache.commons.math3.distribution
NormalDistribution normalDistribution = new NormalDistribution(10, 3);
double randomValue = normalDistribution.sample();
```
A class is a class, regardless of if it's defined in Java or Kotlin. For the most part, this means you just do the Kotlin thing in Kotlin and the Java thing in Java, regardless of where the class you're using is defined. There are exceptions, like for static methods, but most stuff "just works".
I expect, knowing nothing about the NormalDistribution class, that this will work:
val normalDistribution = NormalDistribution(10.0, 3.0);
val randomValue = normalDistribution.sample();
Ok, so I was wrong initially. I had to change my literals above from (10, 3) to (10.0, 3.0). Here's a difference between Java and Kotlin. Kotlin doesn't do automatic numeric type promotion. So while I could use Integer literals for the equivalent Java code, in Kotlin, I had to use Double literals. But my IDE showed me this right away, including a tooltip message that told me just what was wrong. And this is a Kotlin thing, not a Java thing. The same thing would happen if I tried to call a method defined in Kotlin taking doubles as parameters, and I tried to pass it integers. This had nothing to do with which language NormalDistribution is defined in. After that exercise, I can say for sure that this Kotlin code works fine.
Maybe the issue is more that you just don't know Kotlin very well yet. Part of learning Kotlin is realizing how much of a non-issue it is to use Java classes in Kotlin code.
Related
I'm currently working on some old Java written Android project, but writing new parts in Kotlin which I'm not really familiar with. I need some way to unwrap nullable object(analogue of if let unwrappedMyVar = myVar else {} in Swift), to do this I use myVar?.let {} scope function which unwraps myWar and executes block in case it is not null. But now I'm actually curious how those scope functions are implemented in Kotlin, are the actually compiled to Java anonymous classes ? If so, then it can lead to the same problems that Java anonymous classes have. And it is quite easy to create the leakThank you !Kind Regards,Andre
The scope functions like let, apply, run, or also, as well as many more functions in the Kotlin standard library, are inline functions, which means that the lambdas that you pass to them get inlined in their bodies, and the transformed bodies then get inlined at the call site.
With the scope functions, the resulting bytecode is mostly equivalent to what you would get with just declaring a variable and using it after an explicit if-null-check.
In the "Kotlin for Java-Developers"-course by JetBrains (at Coursera) it is told, that Kotlin-code is compiled to byte-code directly. And that byte-code is then executed on the JVM.
But when I do:
var list = listOf<String>("A", "B", "C")
println(list::class) // => Prints "class java.util.Arrays$ArrayList"
Obviously the normal Java ArrayList is used underneath. So I confused ...
Is Kotlin just some "more modern" syntax thing, which uses Java underneath?
Practically some syntactic sugar, which is put on-top, so that one can write code in a nicier way. But underneath it's still the same old Java-thing.
Is Kotlin just some "more modern" syntax thing, which uses Java underneath?
No. You Kotlin source code >>is<< compiling to bytecodes.
But your code is using the listof Kotlin library function, and the implementation of that function is returning a value that is an instance of a Java class.
Why?
It was probably easier / quicker to implement it that way. (Based on the type of the list object, we can infer that listof is simply calling java.util.Arrays.asList(...).)
There is possibly no advantage in reimplementing it; e.g. no performance benefit.
There are possibly disadvantages; e.g. it is likely to cause problems for people who need their Kotlin code to be interoperable with Java which uses standard Java collection classes.
I am using RAD Studio 10.2 Tokyo and am programming in Delphi.
I am having general problems with a Java object using the JNI libraries.
What I am trying to do is find the maximum audio amplitude of an Android audio source between button presses.
Here is the code that I am using.
var
Form1: TForm1;
Recorder: JMediaRecorder;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not assigned(Recorder) then
begin
Recorder:= TJMediaRecorder.Create();
Recorder.setAudioSource(1);
Recorder.setOutputFormat(1);
Recorder.setAudioEncoder(1);
Recorder.setOutputFile(TPath.GetTempPath+'/test');
Recorder.prepare();
Recorder.start();
end;
Label1.Text:=IntToStr(Recorder.getMaxAmplitude());
end;
This appears to generate multiple issues.
Issue #1:
Although I am aware that in java the Media recorder settings should look something like
Recorder.setAudioSource(MediaRecorder.AudioSource.MIC).
That is not something that I can enter in RAD Studio. I took a look at the API and found that that is supposed to mean an integer of 1. The problem is that it gives me an error saying that it can't find an audio source.
Issue #2:
I need to set a path for the file using
Recorder.setOutputFile()
The problem with this is that it only accepts JStrings as input. I have looked all over the place and found a few people who use
StringToJString('my super cool string')
I think this is a part of a library that I am unaware of though because it doesn't work when I use it.
If you know of another way to get an amplitude reading off an Android audio source I would also accept that as an answer as that is the overall problem I am trying to solve.
In general, within the Delphi Android JNI framework:
Java class types are represented in Delphi using classes that are prefixed with TJ, and Java object instances are represented in Delphi using interfaces that are prefixed with J.
nested Java classes are represented by Delphi classes and interfaces that are named after the parent class name followed by _ followed by the nested class name.
Java static constants/fields/properties/methods are represented in Delphi as sub-properties/methods of a special JavaClass class property.
So, in your case:
the Java MediaRecorder class is represented by the TJMediaRecorder class and JMediaRecorder interface.
the Java MediaRecorder.AudioSource class is represented by the TJMediaRecorder_AudioSource class and JMediaRecorder_AudioSource interface.
the Java MediaRecorder.AudioSource.MIC constant is represented by the TJMediaRecorder_AudioSource.JavaClass.MIC class property:
Recorder.setAudioSource(TJMediaRecorder_AudioSource.JavaClass.MIC);
The same thing applies to the MediaRecorder.setOutputFormat() and MediaRecorder.setAudioEncoder() methods:
Recorder.setOutputFormat(TJMediaRecorder_OutputFormat.JavaClass.THREE_GPP);
Recorder.setAudioEncoder(TJMediaRecorder_AudioEncoder.JavaClass.AMR_NB);
As for strings, JNI knows nothing about Delphi strings, so you must use StringToJString() to convert Delphi strings to JNI strings, and use JStringToString() to convert JNI strings to Delphi strings. Both functions are in the Delphi RTL, specifically in the Androidapi.Helpers unit (XE6+) or Androidapi.JNI.JavaTypes unit (XE5), depending on which version of Delphi you are using.
Recorder.setOutputFile(StringToJString(TPath.Combine(TPath.GetTempPath, 'test')));
What are the caveats that a developer should be aware of while writing reflective code that works both with Java and Kotlin?
For example, I have an existing library that uses reflection and it works well with Java. However, when I use the same with Kotlin, my reflective code doesn't seem to pick up the annotations on fields.
Here are some of the differences that I noticed.
1. Acquiring a Class instance
// Example 1.1 - Java
Class<?> userClass = User.class; // From a class name
userClass = userInstance.getClass(); // OR from an instance
Getting a Java class instance in Kotlin
// Example 1.2 - Kotlin
val userClass = userInstance.javaClass // From an instance
I'm unable to use the .class facility or the .getClass() method in Kotlin as we do in Java.
2. Delegates
When I use delegated properties in a Kotlin class, the properties that I retrieve have the $delegate suffix. This is a bit contrary to the fields that we get in Java (I do understand Kotlin does not have fields, only properties). How does this affect meta-programming?
However, with delegates I see that most of the methods retain their behavior as they do in Java. Are there any other differences that I have to be aware of?
Making Java and Kotlin interoperable for me would require understanding about 1 discussed above, plus other limitations / differences that Kotlin brings to meta-programming.
For example, I have an existing library that uses reflection and it works well with Java. However, when I use the same with Kotlin, my reflective code doesn't seem to pick up the annotations on fields.
Can it be because the fields are private now?
Anyway, there are issues with annotations on fields at the moment, this will be fixed in on of the upcoming milestones.
Some other relevant issues:
https://youtrack.jetbrains.com/issue/KT-5967
https://youtrack.jetbrains.com/issue/KT-4169
https://youtrack.jetbrains.com/issue/KT-3625
I'm unable to use the .class facility or the .getClass() method in Kotlin as we do in Java.
Only the syntax is different: javaClass<C>() works exactly the same as C.class, and x.javaClass does the same thing as x.getClass()
When I use delegated properties in a Kotlin class, the properties that I retrieve have the $delegate suffix.
Minor correction: the fields have the $delegate suffix, not the properties.
However, with delegates I see that most of the methods retain their behavior as they do in Java. Are there any other differences that I have to be aware of?
The docs here give you a detailed description of how delegated properties are implemented.
Making Java and Kotlin interoperable for me would require understanding about 1 discussed above, plus other limitations / differences that Kotlin brings to meta-programming.
The more your Kotlin code resembles Java code, the smaller is the difference from the reflection point of view. If you write idiomatic Kotlin, e.g. use default parameter values, traits, properties, delegates, top-level functions, extensions etc, the classes you get differ from idiomatic Java, otherwise they are closely aligned.
The Scala compiler compiles direct to Java byte code (or .NET CIL). Some of the features of Scala could be re-done in Java straightforwardly (e.g. simple for comprehensions, classes, translating anonymous/inner functionc etc). What are the features that cannot be translated that way?
That is presumably mostly of academic interest. More usefully, perhaps, what are the key features or idioms of Scala that YOU use that cannot be easily represented in Java?
Are there any the other way about? Things that can be done straightforwardly in Java that have no straightforward equivalent in Scala? Idioms in Java that don't translate?
This question, in my opinion, misses the point about by asking us to compare JVM languages by looking at their generated bytecode.
Scala compiles to Java-equivalent bytecode. That is, the bytecode could have been generated by code written in Java. Indeed you can even get scalac to output an intermediate form which looks a lot like Java.
All features like traits (via static forwarders), non-local returns (via exceptions), lazy values (via references) etc are all expressible by a Java program, although possibly in a most-ugly manner!
But what makes scala scala and not Java is what scalac can do for you, before the bytecode is generated. What scalac has going for it, as a statically typed language, is the ability to check a program for correctness, including type correctness (according to its type system) at compile time.
The major difference then between Java and scala (as of course Java is also statically typed), therefore, is scala's type system, which is capable of expressing programmatic relations which java-the-language's type system cannot.For example:
class Foo[M[_], A](m : M[A])
trait Bar[+A]
These concept, that M is a type parameter which itself has type parameters or that Bar is covariant, just do not exist in Java-land.
Traits are one thing that does not have an equivalent. Traits are Interfaces with code in them. You can copy the code to all classes that have a trait mixed in, but that is not the same thing.
Also I believe scala type system is more complete. While it will eventually map to the JVM types (actually suffer erasure). You can express some things in the Scala type system that may not be possible in Java (like variances).
I think, there is no equivalent for dynamically mix in some Traits. In Scala you can add at the time you're creating new objects some Traits, which are mixed in.
For example, we create one dog which is hungry and thirsty and one dog which is just hungry.
val hungryThirstyDog = new Dog with Hungry with Thirsty
val onlyHungryDog = new Dog with Hungry
I don't know an equivalent way to do this in Java. In Java, the inheritance is statically defined.
Implicit conversions don't have a straightforward equivalent in Java.
One feature of scala that I have found a good use for is type reification through Manifests. Since the JVM strips out all type information from generics, scala allows you to conserve this information in variables. This is something that Java reflection AFAIK can't handle, since there are no arguments to types in the bytecode.
The case I needed them was to pattern match on a type of List. This is, I had a VertexBuffer object which stored data on the GPU, that could be constructed from a List of floats or integers. The Manifest code looked approximately like this:
class VertexBuffer[T](data:List[T])(implicit m:Manifest[T]) {
m.toString.match {
case "float" => ...
case "int" => ...
}
}
This link links to a blog post with more information.
There are plenty of SO pages with more information too, like this one.
Three words: higher kinded types.
Your topic is not clear wehther you mean Java the JVM or Java the language. Given that Scala runs on the JVM, the q makes no sense, as we all know Scala runs on the JVM.
Scala has a "native" support for XML. You can build the XML, find elements, match directly in the Scala code.
Examples: http://programming-scala.labs.oreilly.com/ch10.html