이 페이지에서

QJniObject Class

Java Native Interface(JNI)를 편리하게 사용할 수 있도록 래핑한 라이브러리입니다. 더 보기...

헤더: #include <QJniObject>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
다음부터: Qt 6.1부터

공개 함수

QJniObject()
QJniObject(const char *className)
QJniObject(jclass clazz)
QJniObject(jobject object)
(since 6.4) QJniObject(const char *className, Args &&... args)
(since 6.4) QJniObject(jclass clazz, Args &&... args)
QJniObject(const char *className, const char *signature, ...)
QJniObject(jclass clazz, const char *signature, ...)
QJniObject(const QJniObject &other)
QJniObject(QJniObject &&other)
~QJniObject()
(since 6.4) auto callMethod(const char *methodName, Args &&... args) const
(since 6.4) auto callMethod(const char *methodName, const char *signature, Args &&... args) const
(since 6.4) QJniObject callObjectMethod(const char *methodName, Args &&... args) const
QJniObject callObjectMethod(const char *methodName, const char *signature, ...) const
(since 6.2) QByteArray className() const
auto getField(const char *fieldName) const
QJniObject getObjectField(const char *fieldName) const
QJniObject getObjectField(const char *fieldName, const char *signature) const
bool isValid() const
jobject object() const
T object() const
(since 6.2) jclass objectClass() const
auto setField(const char *fieldName, Type value)
auto setField(const char *fieldName, const char *signature, Type value)
(since 6.8) void swap(QJniObject &other)
QString toString() const
QJniObject &operator=(QJniObject &&other)
QJniObject &operator=(T object)
QJniObject &operator=(const QJniObject &other)

정적 공용 멤버

(since 6.7) auto callStaticMethod(const char *methodName, Args &&... args)
(since 6.4) auto callStaticMethod(const char *className, const char *methodName, Args &&... args)
(since 6.4) auto callStaticMethod(jclass clazz, const char *methodName, Args &&... args)
(since 6.4) auto callStaticMethod(jclass clazz, jmethodID methodId, Args &&... args)
(since 6.4) auto callStaticMethod(const char *className, const char *methodName, const char *signature, Args &&... args)
auto callStaticMethod(jclass clazz, const char *methodName, const char *signature, Args &&... args)
(since 6.4) QJniObject callStaticObjectMethod(const char *className, const char *methodName, Args &&... args)
(since 6.4) QJniObject callStaticObjectMethod(jclass clazz, const char *methodName, Args &&... args)
QJniObject callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)
QJniObject callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)
QJniObject callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)
(since 6.4) auto construct(Args &&... args)
QJniObject fromLocalRef(jobject localRef)
QJniObject fromString(const QString &string)
auto getStaticField(const char *fieldName)
auto getStaticField(const char *className, const char *fieldName)
auto getStaticField(jclass clazz, const char *fieldName)
QJniObject getStaticObjectField(const char *className, const char *fieldName)
QJniObject getStaticObjectField(jclass clazz, const char *fieldName)
QJniObject getStaticObjectField(const char *className, const char *fieldName, const char *signature)
QJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *signature)
bool isClassAvailable(const char *className)
auto setStaticField(const char *fieldName, Type value)
auto setStaticField(const char *className, const char *fieldName, Type value)
auto setStaticField(jclass clazz, const char *fieldName, Type value)
auto setStaticField(const char *className, const char *fieldName, const char *signature, Type value)
auto setStaticField(jclass clazz, const char *fieldName, const char *signature, Type value)
bool operator!=(const QJniObject &o1, const QJniObject &o2)
bool operator==(const QJniObject &o1, const QJniObject &o2)

상세 설명

QJniObject 클래스는 Java 객체에 대한 참조를 래핑하여, 해당 객체가 가비지 컬렉션 대상이 되지 않도록 보장하고, 대부분의 JNIEnv 메서드 호출(멤버, 정적) 및 필드(세터, 게터)에 대한 액세스를 제공합니다. 이를 통해 모든 작업에 대해 직접 JNI를 사용할 때 일반적으로 필요했던 많은 반복적인 코드를 제거합니다. 호출된 Java 메서드에서 발생된 예외는 기본적으로 제거되지만, Qt 6.11부터는 호출 측에서 처리할 수도 있습니다.

참고: 이 API는 Android에서 사용하도록 설계 및 테스트되었습니다. 다른 플랫폼에서는 테스트되지 않았습니다.

메서드 시그니처

QJniObject는 제공되거나 추론된 템플릿 인자에 따라 올바른 시그니처를 사용하는 편의 함수를 제공합니다.

jint x = QJniObject::callMethod<jint>("getSize");
QJniObject::callMethod<void>("touch");
jint ret = jString1.callMethod<jint>("compareToIgnoreCase", jString2.object<jstring>());

이러한 함수들은 가변 매개변수 템플릿이며, 컴파일러는 실제 매개변수 유형을 바탕으로 시그니처를 추론합니다. 반환 유형만 명시적으로 지정하면 됩니다. QJniObject는 ` JNI types`를 받는 함수와 ` QtJniTypes ` 유형 매핑으로 선언된 유형에 대해 시그니처 문자열을 추론할 수 있습니다.

// Java class
package org.qtproject.qt;
class TestClass
{
    static TestClass create() { ... }
    static String fromNumber(int x) { ... }
    static String[] stringArray(String s1, String s2) { ... }
}
// C++ code
Q_DECLARE_JNI_CLASS(TestClass, "org/qtproject/qt/TestClass")

// ...
using namespace QtJniTypes;
TestClass testClass = TestClass::callStaticMethod<TestClass>("create");

이를 통해 C++ 코드에서 JNI 시그니처 문자열을 명시적으로 생성할 필요 없이 임의의 Java 및 Android 유형을 다룰 수 있습니다.

명시적 JNI 시그니처

서명을 직접 지정할 수도 있습니다. 이 경우, 서명이 호출하려는 함수와 일치해야 합니다.

  • 클래스 이름은 완전 한정된 형태로 표기해야 합니다. 예: "java/lang/String".
  • 메서드 시그니처는 "(ArgumentsTypes)ReturnType" 형식으로 작성하며, 자세한 내용은 JNI Types 를 참조하십시오.
  • 모든 객체 유형은 QJniObject로 반환됩니다.

아래 예제는 다양한 정적 함수를 호출하는 방법을 보여줍니다:

시그니처 구조는 "(ArgumentsTypes)ReturnType" 입니다. 시그니처 내의 배열 유형에는 [ 접두사가 붙어야 하며, 완전한 유형명( Object )에는 L 접두사와 ; 접미사가 붙어야 합니다. create 함수의 시그니처는 "()Lorg/qtproject/qt/TestClass; 입니다. 두 번째 및 세 번째 함수의 시그니처는 각각 "(I)Ljava/lang/String;" 과 "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;" 입니다.

create() 함수는 다음과 같이 호출할 수 있습니다:

// C++ code
QJniObject testClass = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
                                                          "create",
                                                          "()Lorg/qtproject/qt/TestClass;");

두 번째 및 세 번째 함수의 경우, QJniObject의 템플릿 메서드를 사용하여 암시적 시그니처 문자열을 생성할 수 있지만, 시그니처 문자열을 명시적으로 전달할 수도 있습니다:

// C++ code
QJniObject stringNumber = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
                                                             "fromNumber",
                                                             "(I)Ljava/lang/String;", 10);

암시적 시그니처 생성이 제대로 작동하려면 반환형을 명시적으로 지정해야 합니다:

// C++ code
QJniObject string1 = QJniObject::fromString("String1");
QJniObject string2 = QJniObject::fromString("String2");
QJniObject stringArray = QJniObject::callStaticObjectMethod<jobjectArray>(
                                                            "org/qtproject/qt/TestClass",
                                                            "stringArray",
                                                            string1.object<jstring>(),
                                                            string2.object<jstring>());

첫 번째 템플릿 매개변수가 Java 함수의 반환 유형을 지정하지만, 메서드는 여전히 QJniObject를 반환한다는 점에 유의하십시오.

Java 예외 처리

예외가 발생할 수 있는 Java 함수를 호출한 후에는, 처리를 계속하기 전에 예외를 확인하고, 처리하고, 해제하는 것이 중요합니다. 모든 QJniObject 함수는 예외를 보고하고 제거함으로써 내부적으로 예외를 처리할 수 있습니다. 여기에는 JNI 예외(예: 존재하지 않는 메서드를 호출하려고 하거나 잘못된 매개변수를 전달한 경우)와, 오류를 보고하거나 실패 정보를 반환하기 위해 메서드에서 던지는 예외가 포함됩니다.

Qt 6.11부터는 클라이언트 코드가 각 호출에서 예외를 명시적으로 처리하도록 선택할 수 있습니다. 이를 위해 반환 유형으로 C++ 23의 ` std::expected `를 사용하고, 값 유형은 예상되는 값을, 오류 유형은 ` jthrowable `를 지정합니다. 예를 들어, ` android.provider.Settings.Secure ` 유형을 통해 설정 값을 읽으려고 할 때, 해당 설정이 존재하지 않으면 예외가 발생할 수 있습니다.

Q_DECLARE_JNI_CLASS(SettingsSecure, "android/provider/Settings$Secure")
using namespace QtJniTypes;

QString enabledInputMethods()
{
    ContentResolver resolver;
    SettingsSecure settings;

    auto defaultInputMethods = settings.callMethod<std::expected<QString, jthrowable>>(
        "getString", resolver, u"enabled_input_methods"_s
    );
    if (defaultInputMethods)
        return defaultInputMethods.value();
    QStringList stackTrace = QJniEnvironment::stackTrace(defaultInputMethods.error());
}

std::expected 과 유사하게 동작하는 다른 유형을 사용할 수 있으므로, C++23을 사용하지 않고도 예외를 명시적으로 처리할 수 있습니다. 유일한 요구 사항은 해당 유형이 value_type, error_type, unexpected_type 의 세 가지 중첩 유형을 선언하고, 값 유형과 jthrowable 를 포함하는 unexpected_type 로부터 생성될 수 있어야 한다는 점입니다.

참고: JNIEnv 를 직접 사용하여 JNI 호출을 수행할 때는사용자가 예외를 수동으로 처리해야 합니다. 예외가 대기 중인 상태에서 다른 JNI 호출을 수행하는 것은 안전하지 않습니다. 자세한 내용은 QJniEnvironment::checkAndClearExceptions()을 참조하십시오.

Java 네이티브 메서드

Java 네이티브 메서드를 사용하면 Java에서 네이티브 코드를 호출할 수 있습니다. 이는 Java에서 함수 선언을 생성하고 그 앞에 native 키워드를 붙임으로써 이루어집니다. Java에서 네이티브 함수를 호출하기 전에, Java 네이티브 함수를 코드 내의 네이티브 함수에 매핑해야 합니다. 함수 매핑은 QJniEnvironment::registerNativeMethods()를 호출하여 수행할 수 있습니다.

아래 예제는 이를 수행하는 방법을 보여줍니다.

Java 구현:

class FooJavaClass
{
    public static void foo(int x)
    {
        if (x < 100)
            callNativeOne(x);
        else
            callNativeTwo(x);
    }

private static native void callNativeOne(int x);
private static native void callNativeTwo(int x);

}

C++ 구현:

static void fromJavaOne(JNIEnv *env, jobject thiz, jint x)
{
    Q_UNUSED(env);
    Q_UNUSED(thiz);
    qDebug() << x << "< 100";
}

static void fromJavaTwo(JNIEnv *env, jobject thiz, jint x)
{
    Q_UNUSED(env);
    Q_UNUSED(thiz);
    qDebug() << x << ">= 100";
}

void foo()
{
    // 먼저 네이티브 메서드를 등록합니다. 가급적이면 앱 시작 시에 수행하는 것이 좋습니다.
    const JNINativeMethod methods[] =
                {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
                 {"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
    QJniEnvironment env;
    env.registerNativeMethods("my/java/project/FooJavaClass", methods, 2);

    // C++ 함수로 콜백을 수행하는 자바 메서드를 호출합니다
    QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 10);  // 출력: 10 < 100
    QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 100); // 출력: 100 >= 100
}

Java 객체의 수명

Java에서 전달받는 대부분의 objects 는 로컬 참조이며, 네이티브 메서드에서 반환될 때까지만 유효합니다. 그 이후에는 해당 객체가 가비지 컬렉션 대상이 됩니다. 코드에서 루프 내에서 많은 로컬 참조를 생성하는 경우, 각 반복마다 수동으로 해당 참조를 삭제해야 합니다. 그렇지 않으면 메모리가 부족해질 수 있습니다. 자세한 내용은 ‘JNI 설계 개요: 전역 및 로컬 참조’를 참조하십시오. 네이티브 메서드 범위 외부에서 생성된 로컬 참조는 AttachCurrentThread를 사용하고 있으므로 가비지 컬렉터가 자동으로 해제하지 않으므로 수동으로 삭제해야 합니다. 자세한 내용은 ‘JNI 팁: 로컬 및 전역 참조’를 참조하십시오.

Java 객체를 계속 유지하려면, 해당 객체에 대한 새로운 전역 참조를 생성하여 작업이 끝나면 해제하거나, 새로운 QJniObject를 생성하여 Java 객체의 수명을 관리하도록 해야 합니다.

참고: QJniObject는 자체 참조만 관리합니다. 전역 또는 로컬 참조를 사용하여 QJniObject를 생성하는 경우, 해당 참조는 QJniObject에 의해 해제되지 않습니다.

JNI 유형

객체 유형

유형시그니처
jobjectLjava/lang/Object;
jclassLjava/lang/Class;
jstringLjava/lang/String;
jthrowableLjava/lang/Throwable;
jobjectArray[Ljava/lang/Object;
jarray[<type>
jbooleanArray[Z
jbyteArray[B
jcharArray[C
jshortArray[S
jintArray[I
jlongArray[J
jfloatArray[F
jdoubleArray[D

기본 데이터형

형식시그니처
jbooleanZ
jbyteB
jcharC
jshortS
jintI
jlongJ
jfloatF
jdoubleD

기타

유형서명
무효V
사용자 정의 유형L<완전 한정명>;

JNI에 대한 자세한 내용은 Java Native Interface 사양을 참조하십시오.

QJniEnvironment 및 object()도 참조하십시오 .

멤버 함수 문서

QJniObject::QJniObject()

유효하지 않은 JNI 객체를 생성합니다.

isValid()도 참조하십시오 .

[explicit] QJniObject::QJniObject(const char *className)

className 의 기본 생성자를 호출하여 새로운 JNI 객체를 생성합니다.

QJniObject myJavaString("java/lang/String");

[explicit] QJniObject::QJniObject(jclass clazz)

clazz 의 기본 생성자를 호출하여 새로운 JNI 객체를 생성합니다.

참고: QJniObject는 clazz 클래스에 대한 새로운 참조를 생성하며, 소멸될 때 이를 다시 해제합니다. QJniObject 외부에서 생성된 클래스에 대한 참조는 호출자가 직접 관리해야 합니다.

QJniObject::QJniObject(jobject object)

Java 객체 ` object`을 기반으로 새로운 JNI 객체를 생성합니다.

참고: QJniObject는 Java 객체 object 에 대한 참조를 보유하며, 소멸될 때 이를 해제합니다. QJniObject 외부에서 Java 객체 object 에 대한 모든 참조는 호출자가 관리해야 합니다. 대부분의 경우, 로컬 참조를 직접 관리할 의도가 없는 한 이 함수를 로컬 참조로 호출해서는 안 됩니다. 로컬 참조를 QJniObject로 변환하는 방법은 QJniObject::fromLocalRef()을 참조하십시오.

fromLocalRef()도 참조하십시오 .

[explicit, since 6.4] template <typename... Args> QJniObject::QJniObject(const char *className, Args &&... args)

args 를 인수로 사용하여 className 의 생성자를 호출함으로써 새로운 JNI 객체를 생성합니다. 이 생성자는 모든 args 가 알려진 경우에만 사용할 수 있습니다 JNI Types.

QJniEnvironment env;
char* str = "Hello";
jstring myJStringArg = env->NewStringUTF(str);
QJniObject myNewJavaString("java/lang/String", myJStringArg);

이 함수는 Qt 6.4에서 도입되었습니다.

[explicit, since 6.4] template <typename... Args> QJniObject::QJniObject(jclass clazz, Args &&... args)

clazz args 를 사용하여 인수를 전달해 생성자를 호출함으로써 새로운 JNI 객체를 생성합니다. 이 생성자는 모든 가 알려진 경우에만 사용할 수 있습니다 . args JNI Types

QJniEnvironment env;
jclass myClazz = env.findClass("org/qtproject/qt/TestClass");
QJniObject(myClazz, 3);

이 함수는 Qt 6.4에서 도입되었습니다.

[explicit] QJniObject::QJniObject(const char *className, const char *signature, ...)

` signature `를 사용하여 후속 인자의 유형을 지정하고, ` className `의 생성자를 호출하여 새로운 JNI 객체를 생성합니다.

QJniEnvironment env;
char* str = "Hello";
jstring myJStringArg = env->NewStringUTF(str);
QJniObject myNewJavaString("java/lang/String", "(Ljava/lang/String;)V", myJStringArg);

[explicit] QJniObject::QJniObject(jclass clazz, const char *signature, ...)

` clazz `에서 새로운 JNI 객체를 생성합니다. 이때 ` signature `을 사용하여 생성자를 호출하고, 뒤따르는 인수의 유형을 지정합니다.

QJniEnvironment env;
jclass myClazz = env.findClass("org/qtproject/qt/TestClass");
QJniObject(myClazz, "(I)V", 3);

[noexcept default] QJniObject::QJniObject(const QJniObject &other)

QJniObject 의 인스턴스를 복사 생성합니다.

[noexcept default] QJniObject::QJniObject(QJniObject &&other)

QJniObject 의 인스턴스를 move-construct로 생성합니다.

[noexcept] QJniObject::~QJniObject()

JNI 객체를 파기하고, JNI 객체가 보유하고 있는 모든 참조를 해제합니다.

[since 6.4] template <typename ReturnType = void, typename... Args> auto QJniObject::callMethod(const char *methodName, Args &&... args) const

args 를 인수로 하여 methodName 메서드를 호출하고, Ret이 void 가 아닌 경우 해당 값을 반환합니다. Ret이 jobject 유형인 경우, 반환되는 값은 QJniObject 가 됩니다.

QJniObject myJavaString("org/qtproject/qt/TestClass");
jint size = myJavaString.callMethod<jint>("length");

메서드 시그니처는 컴파일 시점에 Ret와 args 의 타입을 기반으로 추론됩니다. Ret는 값을 반환하는 std::expected 호환 타입이거나, 호출된 메서드에 의해 any Java exception thrown 일 수 있습니다.

이 함수는 Qt 6.4에서 도입되었습니다.

[since 6.4] template <typename ReturnType = void, typename... Args> auto QJniObject::callMethod(const char *methodName, const char *signature, Args &&... args) const

객체의 ` methodName ` 메서드를 호출하며, ` signature `을 통해 후속 인자 ` args`의 유형을 지정하고, `Ret`이 ` void`가 아닌 경우 해당 값을 반환합니다. `Ret`이 `jobject` 유형인 경우, 반환되는 값은 ` QJniObject`가 됩니다.

QJniObject myJavaString("org/qtproject/qt/TestClass");
jint index = myJavaString.callMethod<jint>("indexOf", "(I)I", 0x0051);

이 함수는 Qt 6.4에서 도입되었습니다.

[since 6.4] template <typename Ret, typename... Args> QJniObject QJniObject::callObjectMethod(const char *methodName, Args &&... args) const

args 를 인수로 사용하여 Java 객체의 methodName 메서드를 호출하고, 반환된 Java 객체에 대한 새로운 QJniObject 를 반환합니다.

QJniObject myJavaString = QJniObject::fromString("Hello, Java");
QJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString");

메서드 시그니처는 컴파일 시점에 Ret 및 args 의 유형을 기반으로 추론됩니다. Ret은 값을 반환하는 std::expected 호환 유형이거나, 호출된 메서드가 반환하는 any Java exception thrown 일 수 있습니다.

이 함수는 Qt 6.4에서 도입되었습니다.

QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const

Java 객체의 ` methodName ` 메서드를 호출하며, ` signature `을 사용하여 뒤따르는 인수의 유형을 지정합니다.

QJniObject myJavaString = QJniObject::fromString("Hello, Java");
QJniObject mySubstring = myJavaString.callObjectMethod("substring",
                                                       "(II)Ljava/lang/String;", 7, 11);

[static, since 6.7] template < typename Klass, typename ReturnType = void, typename... Args > auto QJniObject::callStaticMethod(const char *methodName, Args &&... args)

Klass 클래스의 정적 메서드 methodName 를 호출하고, Ret 유형의 값을 반환합니다(Ret가 void 인 경우는 제외). Ret가 jobject 유형인 경우, 반환되는 값은 QJniObject 가 됩니다.

메서드 시그니처는 컴파일 시점에 Ret와 args 의 타입을 기반으로 추론됩니다. Klass 는 Java 타입에 매핑된 등록된 타입을 가진 C++ 타입이어야 합니다. Ret는 값을 반환하는 std::expected 호환 타입이거나, 호출된 메서드에 의해 any Java exception thrown 가 될 수 있습니다.

이 함수는 Qt 6.7에서 도입되었습니다.

[static, since 6.4] template <typename ReturnType = void, typename... Args> auto QJniObject::callStaticMethod(const char *className, const char *methodName, Args &&... args)

className 클래스의 정적 메서드 methodName 를 인자 args 와 함께 호출하고, Ret 유형의 값을 반환합니다(Ret가 void 인 경우는 제외). Ret가 jobject 유형인 경우, 반환되는 값은 QJniObject 가 됩니다.

jint value = QJniObject::callStaticMethod<jint>("MyClass", "staticMethod");

메서드 시그니처는 컴파일 시점에 Ret와 args 의 유형을 기반으로 추론됩니다. Ret는 값을 반환하는 std::expected 호환 유형이거나, 호출된 메서드에 의해 any Java exception thrown 일 수 있습니다.

이 함수는 Qt 6.4에서 도입되었습니다.

[static, since 6.4] template <typename ReturnType = void, typename... Args> auto QJniObject::callStaticMethod(jclass clazz, const char *methodName, Args &&... args)

clazz 에 대한 정적 메서드 methodName 를 호출하고, Ret 유형의 값을 반환합니다(Ret가 void 인 경우는 제외). Ret가 jobject 유형인 경우, 반환되는 값은 QJniObject 가 됩니다.

QJniEnvironment env;
jclass javaMathClass = env.findClass("java/lang/Math");
jdouble randNr = QJniObject::callStaticMethod<jdouble>(javaMathClass, "random");

메서드 시그니처는 컴파일 시 Ret와 args 의 타입을 기반으로 추론됩니다. Ret는 값을 반환하는 std::expected 호환 타입이거나, 호출된 메서드에 의해 any Java exception thrown 일 수 있습니다.

이 함수는 Qt 6.4에서 도입되었습니다.

[static, since 6.4] template <typename ReturnType = void, typename... Args> auto QJniObject::callStaticMethod(jclass clazz, jmethodID methodId, Args &&... args)

clazz 클래스의 methodId 로 식별되는 정적 메서드를 뒤따르는 인자들과 함께 호출하고, Ret 유형의 값을 반환합니다(Ret가 void 인 경우는 제외). Ret가 jobject 유형인 경우, 반환되는 값은 QJniObject 가 됩니다.

이 함수는 이전 연산에서 clazz 및 methodId 가 이미 캐시된 경우 유용합니다.

QJniEnvironment env;
jclass javaMathClass = env.findClass("java/lang/Math");
jmethodID methodId = env.findStaticMethod(javaMathClass, "max", "(II)I");
if (methodId != 0) {
    jint a = 2;
    jint b = 4;
    jint max = QJniObject::callStaticMethod<jint>(javaMathClass, methodId, a, b);
}

이 함수는 Qt 6.4에서 도입되었습니다.

[static, since 6.4] template <typename Ret = void, typename... Args> auto QJniObject::callStaticMethod(const char *className, const char *methodName, const char *signature, Args &&... args)

className 클래스의 정적 메서드 ` methodName `를 호출하며, ` signature `를 통해 후속 인자의 유형 ` args`을 지정합니다. 메서드의 결과를 반환합니다(단, `Ret`가 ` void`인 경우는 제외). `Ret`가 `jobject` 유형인 경우, 반환 값은 ` QJniObject`가 됩니다.

jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>("java/lang/Math", "max", "(II)I", a, b);

이 함수는 Qt 6.4에서 도입되었습니다.

[static] template <typename Ret = void, typename... Args> auto QJniObject::callStaticMethod(jclass clazz, const char *methodName, const char *signature, Args &&... args)

clazz 의 정적 메서드 ` methodName `를 호출하며, ` signature `를 사용하여 후속 인자의 유형을 지정합니다. 메서드의 결과를 반환합니다(단, `Ret`가 ` void`인 경우는 제외). `Ret`가 `jobject` 유형인 경우, 반환 값은 ` QJniObject`가 됩니다.

QJniEnvironment env;
jclass javaMathClass = env.findClass("java/lang/Math");
jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>(javaMathClass, "max", "(II)I", a, b);

[static, since 6.4] template <typename Ret, typename... Args> QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName, Args &&... args)

className 클래스의 methodName 를 사용하여 args 인수를 전달하고, 반환된 Java 객체에 대한 새로운 QJniObject 를 반환합니다.

QJniObject string = QJniObject::callStaticObjectMethod<jstring>("CustomClass", "getClassName");

메서드 시그니처는 컴파일 시점에 Ret 및 args 의 타입을 기반으로 추론됩니다. Ret는 값을 반환하는 std::expected 호환 타입이거나, 호출된 메서드가 반환하는 any Java exception thrown 일 수 있습니다.

이 함수는 Qt 6.4에서 도입되었습니다.

[static, since 6.4] template <typename Ret, typename... Args> QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName, Args &&... args)

clazz 의 ` methodName ` 메서드를 호출하여 인자 ` args`를 전달하고, 반환된 Java 객체에 대한 새로운 ` QJniObject `를 반환합니다.

이 함수는 Qt 6.4에서 도입되었습니다.

[static] QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)

clazz 클래스의 ` methodId `로 식별되는 정적 메서드를, 뒤따르는 인자와 함께 호출합니다. 이전 작업에서 ` clazz ` 및 ` methodId `가 이미 캐시에 저장되어 있을 때 유용합니다.

QJniEnvironment env;
jclass clazz = env.findClass("java/lang/String");
jmethodID methodId = env.findStaticMethod(clazz, "valueOf", "(I)Ljava/lang/String;");
if (methodId != 0)
    QJniObject str = QJniObject::callStaticObjectMethod(clazz, methodId, 10);

[static] QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)

className 클래스의 정적 메서드 ` methodName `를 호출하며, ` signature `를 사용하여 그 뒤의 인자 유형을 지정합니다.

QJniObject thread = QJniObject::callStaticObjectMethod("java/lang/Thread", "currentThread",
                                                       "()Ljava/lang/Thread;");
QJniObject string = QJniObject::callStaticObjectMethod("java/lang/String", "valueOf",
                                                       "(I)Ljava/lang/String;", 10);

[static] QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)

clazz 클래스의 정적 메서드 ` methodName `을 호출하며, ` signature `을 사용하여 이후 인자의 유형을 지정합니다.

[since 6.2] QByteArray QJniObject::className() const

QJniObject 가 보유한 클래스 객체의 이름을 QByteArray 형식으로 반환합니다.

이 함수는 Qt 6.2에서 도입되었습니다.

[static, since 6.4] template <typename Class, typename... Args> auto QJniObject::construct(Args &&... args)

Class 과 동등한 Java 클래스의 인스턴스를 생성하고, JNI 객체를 포함하는 QJniObject 를 반환합니다. args 의 인수는 Java 생성자에 전달됩니다.

QJniObject javaString = QJniObject::construct<jstring>();

이 함수는 모든 args 가 JNI Types 로 알려진 경우에만 사용할 수 있습니다.

이 함수는 Qt 6.4에서 도입되었습니다.

[static] QJniObject QJniObject::fromLocalRef(jobject localRef)

로컬 JNI 참조 localRef 를 사용하여 QJniObject 를 생성합니다. 이 함수는 localRef 에 대한 소유권을 인수한 후, 반환하기 전에 이를 해제합니다.

참고: 이 함수는 로컬 JNI 참조에대해서만 호출해야 합니다. 예를 들어, JNI 환경을 통해 이루어지는 대부분의 원시 JNI 호출은 java 객체에 대한 로컬 참조를 반환합니다.

jobject localRef = env->GetObjectArrayElement(array, index);
QJniObject element = QJniObject::fromLocalRef(localRef);

[static] QJniObject QJniObject::fromString(const QString &string)

QString string 를 사용하여 Java 문자열을 생성하고, 해당 문자열을 포함하는 QJniObject 을 반환합니다.

QString myQString = "QString";
QJniObject myJavaString = QJniObject::fromString(myQString);

toString()도 참조하십시오 .

template <typename Type> auto QJniObject::getField(const char *fieldName) const

fieldName 필드의 값을 가져옵니다.

QJniObject volumeControl("org/qtproject/qt/TestClass");
jint fieldValue = volumeControl.getField<jint>("FIELD_NAME");

template <typename T> QJniObject QJniObject::getObjectField(const char *fieldName) const

fieldName 필드에서 JNI 객체를 가져옵니다.

QJniObject field = jniObject.getObjectField<jstring>("FIELD_NAME");

QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const

signature 를 사용하여 fieldName 필드에서 JNI 객체를 가져옵니다.

참고: 이 함수는 템플릿 유형 없이도 사용할 수 있습니다.

QJniObject field = jniObject.getObjectField("FIELD_NAME", "Ljava/lang/String;");

[static] template <typename Klass, typename T> auto QJniObject::getStaticField(const char *fieldName)

Klass 클래스의 정적 필드 ` fieldName `에서 값을 가져옵니다.

Klass Java 타입으로 매핑된 등록된 타입을 가진 C++ 타입이어야 합니다.

[static] template <typename Type> auto QJniObject::getStaticField(const char *className, const char *fieldName)

className 클래스의 정적 필드 ` fieldName `에서 값을 가져옵니다.

[static] template <typename Type> auto QJniObject::getStaticField(jclass clazz, const char *fieldName)

clazz 의 정적 필드 fieldName 에서 값을 가져옵니다.

[static] template <typename T> QJniObject QJniObject::getStaticObjectField(const char *className, const char *fieldName)

className 클래스의 fieldName 필드에서 객체를 가져옵니다.

QJniObject jobj = QJniObject::getStaticObjectField<jstring>("class/with/Fields", "FIELD_NAME");

[static] template <typename T> QJniObject QJniObject::getStaticObjectField(jclass clazz, const char *fieldName)

clazz 의 fieldName 필드에서 객체를 가져옵니다.

QJniObject jobj = QJniObject::getStaticObjectField<jstring>(clazz, "FIELD_NAME");

[static] QJniObject QJniObject::getStaticObjectField(const char *className, const char *fieldName, const char *signature)

className 클래스의 signature 를 사용하여 fieldName 필드에서 JNI 객체를 가져옵니다.

참고: 이 함수는 템플릿 유형 없이도 사용할 수 있습니다.

QJniObject jobj = QJniObject::getStaticObjectField("class/with/Fields", "FIELD_NAME",
                                                   "Ljava/lang/String;");

[static] QJniObject QJniObject::getStaticObjectField(jclass clazz, const char *fieldName, const char *signature)

clazz 클래스의 signature 를 가진 fieldName 필드에서 JNI 객체를 가져옵니다.

참고: 이 함수는 템플릿 유형 없이도 사용할 수 있습니다.

QJniObject jobj = QJniObject::getStaticObjectField(clazz, "FIELD_NAME", "Ljava/lang/String;");

[static] bool QJniObject::isClassAvailable(const char *className)

Java 클래스 className 를 사용할 수 있는 경우 true를 반환합니다.

if (QJniObject::isClassAvailable("java/lang/String")) {
    // condition statement
}

bool QJniObject::isValid() const

이 인스턴스가 유효한 Java 객체를 포함하고 있는 경우 true를 반환합니다.

QJniObject qjniObject;                        // ==> isValid() == false
QJniObject qjniObject(0)                      // ==> isValid() == false
QJniObject qjniObject("could/not/find/Class") // ==> isValid() == false

jobject QJniObject::object() const

template <typename T> T QJniObject::object() const

QJniObject 가 보유한 객체를 jobject 또는 T 형식으로 반환합니다. T는 JNI Object Types 중 하나일 수 있습니다.

QJniObject string = QJniObject::fromString("Hello, JNI");
jstring jstring = string.object<jstring>();

참고: 반환된객체는 여전히 이 ` QJniObject`에 의해 유지됩니다. 이 ` QJniObject`의 수명 이후에도 객체를 유지하려면(예: 나중에 사용하기 위해 기록하는 경우), 가장 쉬운 방법은 적절한 수명을 가진 다른 ` QJniObject `에 객체를 저장하는 것입니다. 또는, 객체에 대한 새로운 전역 참조를 생성하여 저장할 수도 있으며, 사용이 끝나면 반드시 해제해야 합니다.

void functionScope()
{
    QString helloString("Hello");
    jstring myJString = 0;
    {
        QJniObject string = QJniObject::fromString(helloString);
        myJString = string.object<jstring>();
    }

    // Ops! myJString is no longer valid.
    QString myQtString = QJniObject(myJString).toString();
}

[since 6.2] jclass QJniObject::objectClass() const

QJniObject 가 보유한 클래스 객체를 jclass 형태로 반환합니다.

참고: 반환된객체는 여전히 이 ` QJniObject`에 의해 유지됩니다. 이 ` QJniObject`의 수명 이후에도 객체를 유지하려면(예를 들어, 나중에 사용하기 위해 기록해 두는 경우), 가장 쉬운 방법은 적절한 수명을 가진 다른 ` QJniObject `에 객체를 저장하는 것입니다. 또는, 객체에 대한 새로운 전역 참조를 생성하여 저장할 수 있으며, 사용이 끝나면 반드시 해제해야 합니다.

이 함수는 Qt 6.2에서 도입되었습니다.

template <typename Ret = void, typename Type> auto QJniObject::setField(const char *fieldName, Type value)

fieldName 의 값을 value 로 설정합니다.

QJniObject obj;
obj.setField<jint>("AN_INT_FIELD", 10);
jstring myString = ...;
obj.setField<jstring>("A_STRING_FIELD", myString);

template <typename Ret = void, typename Type> auto QJniObject::setField(const char *fieldName, const char *signature, Type value)

` signature `를 사용하여 ` fieldName `의 값을 ` value`로 설정합니다.

QJniObject stringArray = ...;
QJniObject obj = ...;
obj.setObjectField<jobjectArray>("KEY_VALUES", "([Ljava/lang/String;)V",
                           stringArray.object<jobjectArray>())

[static] template < typename Klass, typename Ret = void, typename Type > auto QJniObject::setStaticField(const char *fieldName, Type value)

Klass 클래스의 정적 필드 ` fieldName `을 ` value`으로 설정합니다.

Klass Java 유형으로 매핑된 등록된 유형을 가진 C++ 유형이어야 합니다.

[static] template <typename Ret = void, typename Type> auto QJniObject::setStaticField(const char *className, const char *fieldName, Type value)

className 클래스의 정적 필드 ` fieldName `를 ` value`로 설정합니다.

[static] template <typename Ret = void, typename Type> auto QJniObject::setStaticField(jclass clazz, const char *fieldName, Type value)

clazz 클래스의 정적 필드 ` fieldName `을 ` value`으로 설정합니다.

[static] template <typename Ret = void, typename Type> auto QJniObject::setStaticField(const char *className, const char *fieldName, const char *signature, Type value)

signature 를 사용하는 세터 메서드를 통해 className 클래스의 정적 필드 ` fieldName `를 ` value `로 설정합니다.

[static] template <typename Ret = void, typename Type> auto QJniObject::setStaticField(jclass clazz, const char *fieldName, const char *signature, Type value)

signature 를 사용하여 setter를 통해 clazz 클래스의 정적 필드 ` fieldName `을 ` value `으로 설정합니다.

[noexcept, since 6.8] void QJniObject::swap(QJniObject &other)

이 객체를 ` other`와 교체합니다. 이 작업은 매우 빠르며 절대 실패하지 않습니다.

이 함수는 Qt 6.8에서 도입되었습니다.

QString QJniObject::toString() const

Java 객체의 문자열 표현을 담은 ` QString `를 반환합니다. Java `String` 객체에 대해 이 함수를 호출하면 실제 문자열 데이터를 편리하게 얻을 수 있습니다.

QJniObject string = ...; //  "Hello Java"
QString qstring = string.toString(); // "Hello Java"

fromString()도 참조하십시오 .

[noexcept default] QJniObject &QJniObject::operator=(QJniObject &&other)

other 를 이 QJniObject 인스턴스에 할당합니다.

template <typename T, std::enable_if_t<std::is_convertible_v<T, jobject>, bool> = true> QJniObject &QJniObject::operator=(T object)

현재 객체를 ` object`로 교체합니다. 기존 Java 객체는 해제됩니다.

[noexcept default] QJniObject &QJniObject::operator=(const QJniObject &other)

other 를 이 QJniObject 인스턴스에 복사-할당합니다.

관련 비회원

bool operator!=(const QJniObject &o1, const QJniObject &o2)

o1 가 o2 와는 다른 객체에 대한 참조를 가지고 있는 경우 true를 반환합니다.

bool operator==(const QJniObject &o1, const QJniObject &o2)

o1 와 o2 두 객체가 모두 동일한 Java 객체를 참조하고 있거나, 둘 다 NULL인 경우 true를 반환합니다. 그 외의 모든 경우에는 false가 반환됩니다.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.