Kotlin で static なメンバーをどう書くべきなのか?

092: Learning Kotlin – dealing with static-ness and (companion) objects costs – Fragmented

「companion object」だな. と思いながらとりあえず書く.


class Foo {
    companion object {
        val myVar = "testing"
    }
}

これを Kotlin から呼ぶ場合は,


Foo.myVar

ですが, Java から呼ぶ場合は,


Foo.Companion.getMyVar();

となり クソですね.

では, Jvm アノテーション を使います.


class Foo {
    companion object {
        @JvmField val myVar = "testing"
    }
}

この場合は Kotlin/Java それぞれ同じように呼べます.


// calling from Kotlin
Foo.myVar

// calling from Java
Foo.myVar;

なるべく入れたくないですよね Jvm なアノテーション.

const キーワード を使う


class Foo {
    companion object {
        const val myVar = "testing"
    }
}

以下, 共に問題ありません.


// calling from Kotlin
Foo.myVar

// calling from Java
Foo.myVar;

同様に, パッケージレベルでは,


class BottomSheetView {
    companion object {
        const val BOTTOM_SHEET_ANIMATION_TIMING = 500L
    }

    // ...
}


animation.setTiming(BottomSheetView.BOTTOM_SHEET_ANIMATION_TIMING)

Companion object is initialized from the static constructor of the containing class and plain object is initialized lazily on the first access to that object.

こんなかんじでしっくりくる記述って見つけにくい気がしません? Kotlin て.

“Static constants” in Kotlin | Kotlin Blog


Convert Java File to Kotlin の後に その5 「String Templates」

面倒な文字列の連結.


private static final String SQL_CREATE_ENTRIES =
        "CREATE TABLE " + TasksPersistenceContract.TaskEntry.TABLE_NAME + " (" +
                TasksPersistenceContract.TaskEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + " PRIMARY KEY," +
                TasksPersistenceContract.TaskEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
                TasksPersistenceContract.TaskEntry.COLUMN_NAME_DESCRIPTION + TEXT_TYPE + COMMA_SEP +
                TasksPersistenceContract.TaskEntry.COLUMN_NAME_COMPLETED + BOOLEAN_TYPE +
        " )";

android-architecture/TasksDbHelper.java at todo-mvp · googlesamples/android-architecture

String Templates

「$」マークを使って簡潔に記述できます. ヒアドキュメントのような記述も可能です.

Basic Types - Kotlin Programming Language

これらを使うと上のJavaコードは以下のようになります.


private val SQL_CREATE_ENTRIES =
        """
        CREATE TABLE ${TasksPersistenceContract.TaskEntry.TABLE_NAME} (
            ${TasksPersistenceContract.TaskEntry._ID}$TEXT_TYPE PRIMARY KEY,
            ${TasksPersistenceContract.TaskEntry.COLUMN_NAME_ENTRY_ID}$TEXT_TYPE$COMMA_SEP
            ${TasksPersistenceContract.TaskEntry.COLUMN_NAME_TITLE}$TEXT_TYPE$COMMA_SEP
            ${TasksPersistenceContract.TaskEntry.COLUMN_NAME_DESCRIPTION}$TEXT_TYPE$COMMA_SEP
            ${TasksPersistenceContract.TaskEntry.COLUMN_NAME_COMPLETED}$BOOLEAN_TYPE )
        """

Convert Java File to Kotlin の後に その1「メンバとコンストラクタ」

Convert Java File to Kotlin の後に その2 「apply」

Convert Java File to Kotlin の後に その3 「Null Safety」

Convert Java File to Kotlin の後に その4 「lateinit」

Convert Java File to Kotlin の後に その5 「String Templates」


Convert Java File to Kotlin の後に その4 「lateinit」

ここらのプロパティの初期化です.


public class TasksActivity extends AppCompatActivity {

    private static final String CURRENT_FILTERING_KEY = "CURRENT_FILTERING_KEY";

    private DrawerLayout mDrawerLayout;

    private TasksPresenter mTasksPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tasks_act);

        // Set up the toolbar.
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ActionBar ab = getSupportActionBar();
        ab.setHomeAsUpIndicator(R.drawable.ic_menu);
        ab.setDisplayHomeAsUpEnabled(true);

        // Set up the navigation drawer.
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setStatusBarBackground(R.color.colorPrimaryDark);

android-architecture/TasksActivity.java at todo-mvp · googlesamples/android-architecture

lateinit

Properties and Fields - Kotlin Programming Language

onCreate() などコンストラクタでないライフサイクルに関係するメソッド内での初期化に利用するとよい. 基本的に var と合わせて mutable に.


class TasksActivity : AppCompatActivity() {

    private lateinit var mDrawerLayout: DrawerLayout

    private lateinit var mTasksPresenter: TasksPresenter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.tasks_act)

        // Set up the toolbar.
        val toolbar = findViewById(R.id.toolbar) as Toolbar
        setSupportActionBar(toolbar)
        val ab = supportActionBar
        ab?.setHomeAsUpIndicator(R.drawable.ic_menu)
        ab?.setDisplayHomeAsUpEnabled(true)

        // Set up the navigation drawer.
        mDrawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout
        mDrawerLayout.setStatusBarBackground(R.color.colorPrimaryDark)

Convert Java File to Kotlin の後に その1「メンバとコンストラクタ」

Convert Java File to Kotlin の後に その2 「apply」

Convert Java File to Kotlin の後に その3 「Null Safety」

Convert Java File to Kotlin の後に その4 「lateinit」

Convert Java File to Kotlin の後に その5 「String Templates」