Mobile Development 9 min read

Elegant Kotlin‑Java Mixed Programming for Android Projects

This article explains how to smoothly integrate Kotlin and Java in Android development, covering IDE conversion, class handling, ProGuard pitfalls, library considerations, calling conventions, keyword conflicts, static methods, package‑level functions, and null‑safety with practical code examples.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Elegant Kotlin‑Java Mixed Programming for Android Projects

Kotlin tutorials continue! If you need a quick refresher, see the recommended reading at the end of the article.

The first three chapters help newcomers who must work with Kotlin code immediately, such as a new hire whose codebase is already written in Kotlin.

3.1 Direct Conversion

3.1.1 Converting Java to Kotlin

If you are familiar with Java but new to Kotlin, IntelliJ IDEA can convert Java files to Kotlin with a single command (on macOS the default shortcut is Control + Shift + Command + K, which you may want to customize). The reverse conversion is not supported.

You can modify the shortcut via the IDE’s keymap settings: open Preferences → Keymap, search for "kotlin", and locate the "Convert Java File to Kotlin File" action.

3.1.2 Handling Class References

When converting code that references a class file (e.g., XXX.class ), the automatic conversion fails and you must edit manually. Before Kotlin 1.3 (M13) the equivalent was JavaClass ; after M13 it became XXX::class.java .

3.1.3 Android ProGuard Pitfalls

Our team encountered a ProGuard issue where the following Kotlin code runs fine in debug but is removed after obfuscation:

var str = some?.s?.d ?: ""

Changing the expression to the form below avoids the problem:

var str = some?.s?.d ?: String()

The likely cause is that ProGuard cannot recognize the empty string literal and removes the containing function.

Similar problematic code:

var list = some?.data?.list:mutableListof()

Code that works after obfuscation:

var s = some?.s ?: ""
var s = some.d ?: ""
var list = some?.data?.list:klist 
var data = some?.data ?: return

3.1.4 Advice for Android Library Development

If you are building an Android library, avoid using Kotlin code because it adds roughly 200 KB to a pure‑Java consuming project and may cause compilation errors in some cases.

3.2 Calling Java Code from Kotlin

3.2.1 Methods Returning void

Java methods that return void correspond to Unit in Kotlin; you can omit the return type when calling them.

3.2.2 Resolving Keyword Conflicts

Java’s static keyword is replaced by @JvmStatic in Kotlin. Conversely, Kotlin keywords that do not exist in Java (e.g., in , is , data ) must be escaped with backticks when used in Java code. Example:

// Java code with a method named is()
public void is() {
    // ...
}

// Kotlin conversion with escaped name
fun `is`() {
    // ...
}

3.3 Calling Kotlin Code from Java

3.3.1 Static‑like Methods

Kotlin has no static keyword; to call a Kotlin method from Java via the class name, annotate the method with @JvmStatic . Otherwise, you must access it through an instance.

StringUtils.isEmpty("hello");
StringUtils.INSTANCE.isEmpty2("hello");

object StringUtils {
    @JvmStatic fun isEmpty(str: String): Boolean {
        return "" == str
    }
    fun isEmpty2(str: String): Boolean {
        return "" == str
    }
}

When reading Kotlin code you will often see the companion object pattern:

class StringUtils {
    companion object {
        fun isEmpty(str: String): Boolean {
            return "" == str
        }
    }
}

The companion object acts as an automatically created instance associated with the outer class, allowing calls like StringUtils.isEmpty() from Java.

3.3.2 Package‑Level Functions

Kotlin allows functions to exist outside of a class (package‑level functions). To be callable from Java, the compiler places them in a generated class named ExampleKt . You can rename this class with @file:JvmName("Example") .

3.3.3 Null‑Safety

If a Kotlin function declares a non‑null parameter and Java passes a null value, a NullPointerException is thrown at runtime because Kotlin inserts an assertion. The same occurs when a null object calls a Kotlin method.

Recommended reading:

Kotlin Basics Series

Kotlin Simple Project Series

Kotlin Primer – Chapter 1: Getting Started

Kotlin Primer – Chapter 2: Basic Syntax

Javamobile developmentAndroidKotlinProGuardinteropcode-conversion
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.