How does JVM runtime maintain backward compatibility? - jvm

I have a simple Java class which uses the enum reserved keyword as a variable name. I am able to compile this code in Java 1.4 and execute it in Java 1.6:
public class Main {
public static void main(String[] args) {
String enum = "ENUM String";
System.out.println(enum);
}
}
However the Java 1.6 compiler will not compile this code because enum is a reserved keyword. Why does Java 1.6 runtime still execute this code?

Because when you compile your source code, it is converted into Java bytecode. So the name of your string really doesn't matter once it is compiled.

Related

How to use jssc in Kotlin?

I'm developing a program to measure weight by connecting a PC with an electronic scale.
I'm developing a language with Kotlin, and I'm trying to refer to Java's library, JSSC.
but I don't know what to do because I get a reference error every time.
The development tool is IntelliJ from JetBrain.
import jssc.SerialPortList
object Main {
#JvmStatic
fun main(args: Array<String>) {
val portNames = SerialPortList.getPortNames()
for (i in portNames.indices) {
println(portNames[i])
}
}
}
The top one is a kortlin and the bottom one is a java. I used the translator of the development tool.
import jssc.SerialPortList;
public class Main {
public static void main(String[] args) {
String[] portNames = SerialPortList.getPortNames();
for(int i = 0; i < portNames.length; i++){
System.out.println(portNames[i]);
}
}
}
Java executed, but Kotlin was unable to compile due to errors such as
Unresolved reference:jssc
Unresolved reference: SerialPortList
I'm not sure how to avoid these reference errors, so I'm asking for advice.
Please give me a good answer.
It looks like you want to use java-native/jssc library. The error Unresolved reference is a compilation error. Your code does not have access to the class jssc.SerialPortList. You should follow the instructions on the Github page and add the dependency in your maven or gradle config, or manually add the jar dependency into your Intellij Idea.

How to pass null from Kotlin code to a method taking String as argument in Java library?

I am using microsoft auth (MSAL) SDK in my android app.The SDK is in Java but my app is in Kotlin. I need to pass String as null for the argument loginHint to signIn Java method.
Example in my Kotlin code:-
mSingleAccountApp?.signIn(this#MainActivity, null!!, getScopes(), getAuthInteractiveCallback())
I tried converting the code by pasting into android studio but it converted null to null!! which will give instant NPE.
Method signature in Java library:-
void signIn(#NonNull final Activity activity,
#NonNull final String loginHint,
#NonNull final String[] scopes,
#NonNull final AuthenticationCallback callback);
If the signature weren't marked with #NonNull, you could pass null as String? as a parameter to help the compiler find the right method overload.
But since it's marked #NonNull, the API of this library is saying it is not designed to accept a null parameter. The Kotlin compiler respects many common Java nullability annotations, so it prevents you from even compiling this.
Without looking at its docs, I'd guess you should just pass an empty string "".
It looks like the problem is in the Java declaration: https://github.com/AzureAD/microsoft-authentication-library-for-android/blob/a7b4a07074aef16b1fe36192ae1997203b37b9b3/msal/src/main/java/com/microsoft/identity/client/ISingleAccountPublicClientApplication.java#L66-L86
While loginHint is described as being optional, it is marked as #NonNull in the parameter list, so Kotlin respects this annotation and thinks null is not allowed here.
The best way to deal with it is to file an issue about the incorrect nullability to the library authors (https://github.com/AzureAD/microsoft-authentication-library-for-android/issues), but to work around it for now you can declare a static helper function in java with the right nullability information:
// here I'm using org.jetbrains.annotations to declare the right nullability:
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
// A java helper class
class SingleAccountPublicClientApplicationUtils {
static void signIn(#NotNull final ISingleAccountPublicClientApplication application,
#NotNull final Activity activity,
#Nullable final String loginHint,
#NotNull final String[] scopes,
#NotNull final AuthenticationCallback callback) {
// just call application.signIn, java doesn't care about nullability annotations
application.signIn(activity, loginHint, scopes, callback);
}
}

Kotlin #FunctionalInterface compiles with multiple abstract methods

When trying to compile a Java #FunctionalInterface having more than 1 non-abstract method a compilation error is raised.
However, when doing the same in Kotlin, no errors or warnings are raised, i.e. the following Kotlin interface compiles successfully:
#FunctionalInterface
interface Foo {
fun foo()
fun foo(params: Map<String, String>)
}
Is this the intended behaviour or a bug in the Kotlin compiler?
Please note that the generated bytecode for the above Kotlin snippet is equivalent to the following Java snippet (which – correctly – doesn't compile):
#FunctionalInterface
// metadata omitted
public interface Foo {
void foo();
void foo(#NotNull Map var1);
}
Issue KT-25512 has been submitted to JetBrains's issue tracker (by another user) to report the fact that the compiler misbehaves when #FunctionalInterface is applied to a non-SAM interface, and as of 10 Feb 2019 the issue is still open with no activity.

What is the difference between main and regular function?

Kotlin allows me to create two main() functions. But does not allow two myfun() functions.
What is special about main()? Are there other special functions?
Can I create two static myfun() functions in same package? I want them to have file scope like main.
Test1.kt:
package start
fun main(args: Array<String>) {
}
fun myfun(args: Array<String>) {
}
Test2.kt:
package start
// OK!
fun main(args: Array<String>) {
}
// Error! Conflicting overloads
fun myfun(args: Array<String>) {
}
Kotlin allows to have multiple top-level main functions in the same package due to practical reasons — so that one could have an entry point in an each file without moving these files to different packages.
It is possible because each .kt file with top-level members is compiled to the corresponding class file, so these main functions do not clash, because they are located in separate class files.
Why is it allowed for main functions and not for other top-level functions? Having multiple functions with the same name and signature in the same package would make it impossible to distinguish them when calling from Kotlin. This is not a problem for main function, because when it is used as an entry point for a program, it's required to specify the class name where it is located.
What is special about main()? Are there other special functions?
To start a Java program you need
a class file,
static void main(String[]) method in that class file.
So from outside of the package you'd be able to start any of these main methods.
However if you try to call the main method from another Kotlin file inside of the package, you'd get an error, because Kotlin can't disambiguate one method from the other.
You can call any of them from Java as you please because they're compiled in different class files (see further).
Can I create two static myfun() functions in same package?
You can't define two top-level methods with the same name in the same package in Kotlin (with the above exception).
This is what your code compiles to:
public final class Test1Kt {
public static final void main(#NotNull String[] args) { /* ... */ }
public static final void myFun(#NotNull String[] args) { /* ... */ }
}
public final class Test2Kt {
public static final void main(#NotNull String[] args) { /* ... */ }
public static final void myFun(#NotNull String[] args) { /* ... */ }
}
As far as JVM is concerned all of these methods could coexist in peace. But this is an implementation detail of Kotlin.
Let's forget for a second that Kotlin apps run on JVM. Pretend your only tool is Kotlin, and you can't use Java, perhaps you're writing a Kotlin cross-platform module. How could you have two top-level functions with the same name? How would you pick which one to call? Again, you'd get an error, because Kotlin couldn't disambiguate one method from the other.
Edit: As noted by #Todd this behavior has been even more strict in the past: Why does Kotlin lang allow only single main function in project?
Regarding the question about how to have file-scoped functions, by default top-level functions (those not declared within a class) are public, which means their signatures must be unique, including the package name. You can make functions local to the file, rather than the package, by prefixing them with the private modifier, e.g., in each file:
private fun myfun(args: Array<String>) {
// method body here
}

How does Java compiler handle statically resolvable calls to non-static methods?

Do java compilers (javac or eclipse) try to compile method calls as static when the target method is known statically (even if it's not a static method). Eg.
class A {
void foo() { doStuff(); }
}
...
A a = new A();
a.foo(); // is this compiled as virtual call or static call?
See my response at How to find out what optimizations the JVM applied to my code?