없습니다 static
코 틀린에 키워드 .
static
Kotlin에서 Java 메소드 를 나타내는 가장 좋은 방법은 무엇입니까 ?
없습니다 static
코 틀린에 키워드 .
static
Kotlin에서 Java 메소드 를 나타내는 가장 좋은 방법은 무엇입니까 ?
답변:
"companion object"에 함수를 배치합니다.
따라서 자바 코드는 다음과 같습니다.
class Foo {
public static int a() { return 1; }
}
될 것입니다
class Foo {
companion object {
fun a() : Int = 1
}
}
그런 다음 Kotlin 코드 내부에서 다음과 같이 사용할 수 있습니다
Foo.a();
그러나 Java 코드 내에서 다음과 같이 호출해야합니다.
Foo.Companion.a();
(Kotlin 내에서도 작동합니다.)
Companion
비트 를 지정하지 않으 @JvmStatic
려면 주석을 추가 하거나 컴패니언 클래스의 이름 을 지정할 수 있습니다 .
로부터 문서 :
동반자 객체
클래스 내부의 객체 선언은 companion 키워드로 표시 할 수 있습니다.
class MyClass { companion object Factory { fun create(): MyClass = MyClass() } }
클래스 이름을 한정자로 간단히 사용하여 컴패니언 객체의 멤버를 호출 할 수 있습니다.
val instance = MyClass.create()
...
그러나 JVM에서
@JvmStatic
어노테이션 을 사용하는 경우 컴패니언 오브젝트의 멤버를 실제 정적 메소드 및 필드로 생성 할 수 있습니다 . 자세한 내용은 Java 상호 운용성 섹션을 참조하십시오.
@JvmStatic
주석을 추가하면 다음과 같습니다
class Foo {
companion object {
@JvmStatic
fun a() : Int = 1;
}
}
그러면 Java와 Kotlin에서 모두로 액세스 할 수있는 실제 Java 정적 함수로 존재합니다 Foo.a()
.
Companion
이름이 마음에 들지 않으면 다음과 같이 컴패니언 객체에 대한 명시 적 이름을 제공 할 수도 있습니다.
class Foo {
companion object Blah {
fun a() : Int = 1;
}
}
같은 방식으로 Kotlin에서 호출 할 수 있지만 java와 같은 Foo.Blah.a()
(Kotlin에서도 작동 함).
fun a(): Int { return 1 }
또는 그럴 것입니다fun a(): Int = 1
fun a() = 1
.
Factory
는 컴패니언 객체 의 이름 입니다. 그러나 무엇을 위해 사용할 수 있습니까? 잘 모르겠지만 관심이있어서 stackoverflow.com/q/45853459/221955에 대한 질문을 작성했습니다 .
Docs 는 패키지 수준 함수를 사용 하여 정적 함수에 대한 대부분의 요구를 해결하는 것이 좋습니다 . 그것들은 단순히 소스 코드 파일의 클래스 외부에서 선언됩니다. 파일의 패키지는 파일 시작 부분에서 package 키워드를 사용하여 지정할 수 있습니다.
선언
package foo
fun bar() = {}
용법
import foo.bar
대안 적으로
import foo.*
이제 다음을 사용하여 함수를 호출 할 수 있습니다.
bar()
또는 import 키워드를 사용하지 않는 경우 :
foo.bar()
패키지를 지정하지 않으면 루트에서 기능에 액세스 할 수 있습니다.
자바 경험 만 있다면 조금 이상하게 보일 수 있습니다. 그 이유는 kotlin이 객체 지향 언어가 아니기 때문입니다. 클래스 외부의 메소드를 지원한다고 말할 수 있습니다.
편집 : 더 이상 패키지 레벨 기능 권장에 대한 문장을 포함하지 않도록 문서를 편집했습니다. 이것은 위에서 언급 한 원본입니다.
class FooPackage
모든 최상위 속성과 함수를 사용하여를 만들고 모든 참조를 적절하게 라우팅합니다. jetbrains에서 더 많은 정보.
bar()
파일 이름이 중요하지 않다는 것을 명확히하고 싶었습니다 BarUtils.kt
. 텍스트 이름 과 함께 가져올 것입니다import <package name>.bar
A. 구 자바 웨이 :
companion object
정적 메소드 / 변수 를 포함하도록 a 를 선언 하십시오.
class Foo{
companion object {
fun foo() = println("Foo")
val bar ="bar"
}
}
사용하다 :
Foo.foo() // Outputs Foo
println(Foo.bar) // Outputs bar
B. 뉴 코 틀린 방식
파일 에 클래스 가 없는 파일에 직접 선언 .kt
하십시오.
fun foo() = println("Foo")
val bar ="bar"
이름methods/variables
과 함께를 사용하십시오 . ( 가져온 후 )
사용하다 :
foo() // Outputs Foo
println(bar) // Outputs bar
INSTANCE
과 같은 키워드 가 필요합니다 .Foo.INSTANCE.sayFoo()
static CLASS
아니라면 이 솔루션이 선호되는 방법이라고 생각합니다 static methdos
. 컴패니언 객체를 사용하면 여전히 부모 클래스를 인스턴스화 할 수 있습니다.
val
정적이 아닙니다 static final
. Java 와 동일합니다.
object objectName {
fun funName() {
}
}
kotlin에는 정적 키워드가 없으므로 정적 메소드에 대해 컴패니언 객체를 전달해야합니다. 컴패니언 객체의 멤버는 클래스 이름을 한정자로 사용하여 호출 할 수 있습니다.
package xxx
class ClassName {
companion object {
fun helloWord(str: String): String {
return stringValue
}
}
}
코 틀린에서 정적을 적용 할 수있는 두 가지 방법이 있습니다
먼저 반 아래 동반자 개체를 만듭니다.
예를 들어 :
class Test{
companion object{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
}
이 함수를 다음과 같이 호출 할 수 있습니다
Test.Companion.isCheck(2)
우리가 사용할 수있는 또 다른 방법은 객체 클래스를 만드는 것입니다
object Test{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
행복한 코딩!
Test.Companion.isCheck(2)
IDE) 경고를 표시하고 말합니다 Companion reference is redundant
. 축소 될 수 있고 축소 Test.isCheck(2)
된 형태는 Java와 거의 비슷합니다.
위의 답변에 무언가를 추가하고 싶습니다.
예, 소스 코드 파일 (외부 클래스)에서 함수를 정의 할 수 있습니다. 그러나 Kotlin Extensions 를 활용하여 정적 함수를 더 추가 할 수 있으므로 Companion Object를 사용하여 클래스 내에 정적 함수를 정의하는 것이 좋습니다 .
class MyClass {
companion object {
//define static functions here
}
}
//Adding new static function
fun MyClass.Companion.newStaticFunction() {
// ...
}
또한 Companion Object 내부의 함수를 호출 할 때 위에 정의 된 함수를 호출 할 수 있습니다.
지금은 2 년이 조금 넘었지만 훌륭한 답변을 많이 받았지만 "정적"Kotlin 필드를 얻는 다른 방법이없는 것을보고 있습니다. 다음은 Kotlin-Java static
interop에 대한 예제 안내서입니다 .
시나리오 1 : Kotlin for Java에서 정적 메소드 작성
코 틀린
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Java classes to treat this method as if it was a static to [KotlinClass] @JvmStatic fun foo(): Int = 1 //Without it, you would have to use [KotlinClass.Companion.bar()] to use this method. fun bar(): Int = 2 } }
자바
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo()); //Prints "1" println(KotlinClass.Companion.bar()); //Prints "2". This is the only way to use [bar()] in Java. println(KotlinClass.Companion.foo()); //To show that [Companion] is still the holder of the function [foo()] } //Because I'm way to lazy to keep typing [System.out], but I still want this to be compilable. void println(Object o) { System.out.println(o); } }
마이클 앤더슨의 대답은 이것보다 더 깊이를 제공하며,이 시나리오에서 반드시 참조되어야합니다.
이 다음 시나리오는 Kotlin에서 정적 필드 작성을 처리하므로 KotlinClass.foo()
정적 함수를 원하지 않는 경우 Java를 계속 호출 할 필요가 없습니다.
시나리오 2 : Kotlin for Java에서 정적 변수 작성
코 틀린
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Kotlin to not generate the getter/setter functions in Java. Instead, this variable should be accessed directly //Also, this is similar to [@JvmStatic], in which it tells Java to treat this as a static variable to [KotlinClass]. @JvmField var foo: Int = 1 //If you want something akin to [final static], and the value is a primitive or a String, you can use the keyword [const] instead //No annotation is needed to make this a field of [KotlinClass]. If the declaration is a non-primitive/non-String, use @JvmField instead const val dog: Int = 1 //This will be treated as a member of the [Companion] object only. It generates the getter/setters for it. var bar: Int = 2 //We can still use [@JvmStatic] for 'var' variables, but it generates getter/setters as functions of KotlinClass //If we use 'val' instead, it only generates a getter function @JvmStatic var cat: Int = 9 } }
자바
package com.frybits; class JavaClass { void someFunction() { //Example using @JvmField println(KotlinClass.foo); //Prints "1" KotlinClass.foo = 3; //Example using 'const val' println(KotlinClass.dog); //Prints "1". Notice the lack of a getter function //Example of not using either @JvmField, @JvmStatic, or 'const val' println(KotlinClass.Companion.getBar()); //Prints "2" KotlinClass.Companion.setBar(3); //The setter for [bar] //Example of using @JvmStatic instead of @JvmField println(KotlinClass.getCat()); KotlinClass.setCat(0); } void println(Object o) { System.out.println(o); } }
Kotlin의 가장 큰 특징 중 하나는 최상위 함수와 변수를 만들 수 있다는 것입니다. 이를 통해 상수 필드 및 함수의 "클래스리스"목록을 작성 static
하여 Java에서 함수 / 필드 로 사용할 수 있습니다 .
시나리오 3 : Java에서 Kotlin의 최상위 필드 및 기능에 액세스
코 틀린
//In this example, the file name is "KSample.kt". If this annotation wasn't provided, all functions and fields would have to accessed //using the name [KSampleKt.foo()] to utilize them in Java. Make life easier for yourself, and name this something more simple @file:JvmName("KotlinUtils") package com.frybits //This can be called from Java as [KotlinUtils.TAG]. This is a final static variable const val TAG = "You're it!" //Since this is a top level variable and not part of a companion object, there's no need to annotate this as "static" to access in Java. //However, this can only be utilized using getter/setter functions var foo = 1 //This lets us use direct access now @JvmField var bar = 2 //Since this is calculated at runtime, it can't be a constant, but it is still a final static variable. Can't use "const" here. val GENERATED_VAL:Long = "123".toLong() //Again, no need for @JvmStatic, since this is not part of a companion object fun doSomethingAwesome() { println("Everything is awesome!") }
자바
package com.frybits; class JavaClass { void someFunction() { println(KotlinUtils.TAG); //Example of printing [TAG] //Example of not using @JvmField. println(KotlinUtils.getFoo()); //Prints "1" KotlinUtils.setFoo(3); //Example using @JvmField println(KotlinUtils.bar); //Prints "2". Notice the lack of a getter function KotlinUtils.bar = 3; //Since this is a top level variable, no need for annotations to use this //But it looks awkward without the @JvmField println(KotlinUtils.getGENERATED_VAL()); //This is how accessing a top level function looks like KotlinUtils.doSomethingAwesome(); } void println(Object o) { System.out.println(o); } }
"정적"필드로 Java에서 사용할 수있는 또 다른 주목할만한 것은 Kotlin object
클래스입니다. 이들은 처음 사용할 때 느리게 인스턴스화되는 0 개의 매개 변수 싱글 톤 클래스입니다. 이에 대한 자세한 정보는 여기에서 찾을 수 있습니다.https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations 참조
그러나 싱글 톤에 액세스하기 INSTANCE
위해 처리하기가 성가신 특수한 오브젝트가 작성됩니다 Companion
. static
자바에서 주석을 사용하여 깔끔한 느낌 을주는 방법은 다음과 같습니다 .
시나리오 4 :
object
클래스 사용코 틀린
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits object KotlinClass { //No need for the 'class' keyword here. //Direct access to this variable const val foo: Int = 1 //Tells Java this can be accessed directly from [KotlinClass] @JvmStatic var cat: Int = 9 //Just a function that returns the class name @JvmStatic fun getCustomClassName(): String = this::class.java.simpleName + "boo!" //Getter/Setter access to this variable, but isn't accessible directly from [KotlinClass] var bar: Int = 2 fun someOtherFunction() = "What is 'INSTANCE'?" }
자바
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singleton println(KotlinClass.getCat()); //Getter of [cat] KotlinClass.setCat(0); //Setter of [cat] println(KotlinClass.getCustomClassName()); //Example of using a function of this 'object' class println(KotlinClass.INSTANCE.getBar()); //This is what the singleton would look like without using annotations KotlinClass.INSTANCE.setBar(23); println(KotlinClass.INSTANCE.someOtherFunction()); //Accessing a function in the object class without using annotations } void println(Object o) { System.out.println(o); } }
간단히 말하면 "companion object" 를 사용 하여 Kotlin 정적 세계에 들어갈 수 있습니다.
companion object {
const val TAG = "tHomeFragment"
fun newInstance() = HomeFragment()
}
코드에서와 같이 상수 필드를 "const val" 로 사용 합니다. 그러나 Mockito!를 사용한 단위 테스트에서 어려움을 겪고 있기 때문에 정적 클래스를 피하십시오.
자바 정적 메소드를 kotlin으로 변환하는 정확한 방법은 다음과 같습니다. 예를 들어, 여기에서 util 클래스에는 java와 kotlin 모두에서 동등한 정적 메소드가 있습니다. @JvmStatic 사용 이 중요합니다.
자바 코드 :
class Util{
public static String capitalize(String text){
return text.toUpperCase();}
}
코 틀린 코드 :
class Util {
companion object {
@JvmStatic
fun capitalize(text:String): String {
return text.toUpperCase()
}
}
}
간단히 컴패니언 객체를 만들고 함수를 넣어야합니다.
class UtilClass {
companion object {
// @JvmStatic
fun repeatIt5Times(str: String): String = str.repeat(5)
}
}
kotlin 클래스에서 메소드를 호출하려면 다음을 수행하십시오.
class KotlinClass{
fun main(args : Array<String>) {
UtilClass.repeatIt5Times("Hello")
}
}
또는 가져 오기 사용
import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
fun main(args : Array<String>) {
repeatIt5Times("Hello")
}
}
Java 클래스에서 메소드를 호출하려면 다음을 수행하십시오.
class JavaClass{
public static void main(String [] args){
UtilClass.Companion.repeatIt5Times("Hello");
}
}
또는 메소드에 @JvmStatic 주석을 추가하여
class JavaClass{
public static void main(String [] args){
UtilClass.repeatIt5Times("Hello")
}
}
또는 메소드에 @JvmStatic 주석을 추가하고 Java에서 정적 가져 오기를 수행하여
import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
public static void main(String [] args){
repeatIt5Times("Hello")
}
}
Java의 경우 :
public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}
동등한 코 틀린 코드 :
object Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}
따라서 Java 정적 메소드와 동등한 것은 Kotlin의 객체 클래스입니다.
단일 활동에서 필요한 모든 활동까지 문자열을 사용하는 Android의 경우. 자바에서 정적처럼
public final static String TEA_NAME = "TEA_NAME";
코 틀린에서의 동등한 접근 방식 :
class MainActivity : AppCompatActivity() {
companion object {
const val TEA_NAME = "TEA_NAME"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
가치가 필요한 또 다른 활동 :
val teaName = MainActivity.TEA_NAME
Michael Anderson의 답변을 제외하고는 프로젝트에서 다른 두 가지 방법으로 코딩했습니다.
모든 변수를 하나의 클래스에 흰색으로 표시 할 수 있습니다. Const라는 kotlin 파일을 만들었습니다
object Const {
const val FIRST_NAME_1 = "just"
const val LAST_NAME_1 = "YuMu"
}
kotlin 및 Java 코드에서 사용할 수 있습니다
Log.d("stackoverflow", Const.FIRST_NAME_1)
Kotlin의 확장 기능을 사용하여
Ext라는 kotlin 파일을 만들 수 있습니다 . 아래 코드는 Ext 파일의 모든 코드입니다.
package pro.just.yumu
/**
* Created by lpf on 2020-03-18.
*/
const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"
kotlin 코드에서 사용할 수 있습니다
Log.d("stackoverflow", FIRST_NAME)
당신은 자바 코드에서 사용할 수 있습니다
Log.d("stackoverflow", ExtKt.FIRST_NAME);
파일에 직접 쓰십시오.
Java에서 (못생긴) :
package xxx;
class XxxUtils {
public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}
코 틀린에서 :
@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()
컴파일 된 파일 이름조차도 컴파일 된 파일 이름 file:JvmName
을 제어하는 데 사용되며 패키지 이름 선언 직전에 넣어야합니다.
학생 클래스가 있습니다. 그리고 정적 메소드 getUniversityName () 하나와 totalStudent 라는 정적 필드 하나가 있습니다.
클래스 내에서 컴패니언 객체 블록을 선언해야 합니다.
companion object {
// define static method & field here.
}
그런 다음 수업은 다음과 같습니다
class Student(var name: String, var city: String, var rollNumber: Double = 0.0) {
// use companion object structure
companion object {
// below method will work as static method
fun getUniversityName(): String = "MBSTU"
// below field will work as static field
var totalStudent = 30
}
}
그런 다음 정적 메소드와 필드를 이런 식으로 사용할 수 있습니다.
println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
// Output:
// University : MBSTU, Total Student: 30
kotlin에는 정적 키워드가 없습니다. kotlin docs는 DRY를 따르려면 패키지 수준 기능을 사용하는 것이 좋습니다. 확장명 이 .kt 인 파일을 만들고 메서드를 넣습니다.
package p
fun m(){
//fun body
}
컴파일 후 m 의 서명을 갖습니다 public static final void
과
import p.m
☺
Companion Objects 를 통해 Kotlin의 정적 기능을 달성 할 수 있습니다
동반자 객체는 클래스 외부에 선언 할 수 없습니다.
class MyClass{
companion object {
val staticField = "This is an example of static field Object Decleration"
fun getStaticFunction(): String {
return "This is example of static function for Object Decleration"
}
}
}
클래스 이름을 한정자로 사용하여 컴패니언 객체의 멤버를 호출 할 수 있습니다.
산출:
MyClass.staticField // This is an example of static field Object Decleration
MyClass.getStaticFunction() : // This is an example of static function for Object Decleration
많은 사람들이 컴패니언 객체를 언급하는데 이는 맞습니다. 그러나 아시다시피 클래스가 아닌 객체 키워드를 사용하여 모든 종류의 객체를 사용할 수도 있습니다.
object StringUtils {
fun toUpper(s: String) : String { ... }
}
Java의 정적 메소드와 마찬가지로 사용하십시오.
StringUtils.toUpper("foobar")
이러한 유형의 패턴은 Kotlin에서 쓸모가 없지만 정적 메소드로 채워진 클래스가 필요 없다는 장점이 있습니다. 사용 사례에 따라 전역, 확장 및 / 또는 로컬 기능을 대신 사용하는 것이 더 적합합니다. 내가 일하는 곳에서 우리는 종종 이름 지정 규칙 [className] Extensions.kt, 즉 FooExtensions.kt와 같은 별도의 플랫 파일로 전역 확장 함수를 정의합니다. 그러나 더 일반적으로 우리는 운영 클래스 또는 객체 내부에서 필요한 곳에 함수를 작성합니다.
함수 또는 속성을 인스턴스가 아닌 클래스에 연결해야하는 경우 컴패니언 객체 내에서 선언 할 수 있습니다.
class Car(val horsepowers: Int) {
companion object Factory {
val cars = mutableListOf<Car>()
fun makeCar(horsepowers: Int): Car {
val car = Car(horsepowers)
cars.add(car)
return car
}
}
}
컴패니언 객체는 싱글 톤이며 포함하는 클래스의 이름을 통해 해당 멤버에 직접 액세스 할 수 있습니다.
val car = Car.makeCar(150)
println(Car.Factory.cars.size)
컴패니언 객체 를 사용할 수 있습니다 -kotlinlang
먼저 해당 인터페이스를 생성하여 표시 할 수있는
interface I<T> {
}
그런 다음 해당 인터페이스 내에서 함수를 만들어야합니다.
fun SomeFunc(): T
그런 다음 수업이 필요합니다.
class SomeClass {}
그 클래스 안에서 우리는 그 클래스 안에 동반자 객체가 필요합니다 :
companion object : I<SomeClass> {}
그 Companion Object 내에서 우리는 그 오래된 SomeFunc
기능이 필요하지만 그것을 넘어서야합니다.
override fun SomeFunc(): SomeClass = SomeClass()
마지막으로 그 모든 작업 아래에서 정적 기능을 강화할 수있는 것이 필요합니다. 변수가 필요합니다.
var e:I<SomeClass> = SomeClass()