翻譯參考資料

類型

  • 針對原始類型,J2ObjC 已定義 JNI 式 typedef。
  • 以一般類別類型來說,套件將採用駝峰式大小寫,並在前面加上類別名稱。
  • 基本物件類型和所有類型變數都使用「id」。
  • 部分核心 Java 類型對應至基礎類型。(例如:字串至 NSString)
  • 針對宣告「揮發性」的欄位,J2ObjC 還有更多使用 C11 _Atomic(...) 類型的 typedef。
  • 如果是內部類型,內部類別名稱會加上外部名稱,並加上底線。
Java 類型 Objective-C 類型 Objective-C 揮發性類型
布林值 J 布林值 volatile_j 布林值
字元 Jchar Voatile_jchar
位元組 JBytes volatile_jbyte
short JShort Voatile_jshort
int Jint 揮發性藥
long Jlong 揮發性波動
浮動 Jfloat Voatile_jfloat
雙精度值 Jdouble Voatile_jdouble
java.lang.Object id volatile_id
類型變數 id volatile_id
java.lang.String NSString* volatile_id
java.lang.Number NSNumber*: volatile_id
java.lang.Cloneable NS 複製* volatile_id
foo.bar.Mumble FooBarMumble* volatile_id
foo.bar.Mumber$內心 FooBarMumble_Inner* volatile_id

方法

Objective-C 方法與 Java 方法有兩大不同。兩者的語法不同,在參數選取器之間嵌入參數。Objective-C 方法不支援超載,就像 Java 一樣。只要將參數類型嵌入產生的選取器,即可解決這些差異。這是防止超載 Java 方法之間的名稱衝突。

在產生的 API 中,有三種 Java 方法:執行個體方法、靜態方法和建構函式。執行個體方法會轉換為 Objective-C 執行個體方法。靜態方法和建構函式會轉換為 C 樣式函式,但也會新增 Objective-C 包裝函式,為 Objective-C 開發人員提供更熟悉的 API。

執行個體方法

方法名稱的產生方式如下:

  • 0 參數方法維持不變
  • 一或多個參數使用以下模式:
    • <java name>With<1st param keyword>:with<2nd param keyword>:with<3rd param keyword>:
  • 參數關鍵字規則:
    • 原始類型是指關鍵字是 Java 原始基元的大寫名稱。(例如:「排行榜」)
    • 對於非原始類型,關鍵字是駝峰式大小寫的完整類型名稱。(例如:「ComGoogleFoo」)
    • 如果是陣列類型,會在元素類型的關鍵字後方附加「Array」。
Java 範例
interface Foo {
  void bar();
  String bar(int i);
  java.util.List bar(String s, long[] l);
}
目標 - C 範例
- (void)bar;

- (NSString *)barWithInt:(jint)i;

- (id<JavaUtilList>)barWithNSString:(NSString *)s
                      withLongArray:(IOSLongArray *)l;

靜態方法

我們採用與執行個體方法相同的命名規則加入 Objective-C 類別方法。

系統會使用以下命名規則新增 C 樣式函式:

  • 先使用系統產生的 Objective-C 選取器。(例如:barWithInt:)
  • 使用冒號取代冒號。(例如:barWithInt_)
  • 請在類別名稱前面加上底線,並以底線分隔。(例如:ComGoogleFoo_barWithInt_)
Java 範例
package com.google;
class Foo {
  static boolean bar() { ... }
  static double bar(int[] i) { ... }
  static void bar(String s, boolean b) { ... }
}
目標 - C 範例
@interface Foo : NSObject

+ (jboolean)bar;

+ (jdouble)barWithIntArray:(IOSIntArray *)i;

+ (void)barWithNSString:(NSString *)s
            withBoolean:(jboolean)b;

@end

FOUNDATION_EXPORT jboolean ComGoogleFoo_bar();

FOUNDATION_EXPORT jdouble ComGoogleFoo_barWithIntArray_(IOSIntArray *i);

FOUNDATION_EXPORT void ComGoogleFoo_barWithNSString_withBoolean_(NSString *s, jboolean b);

建構函式

按照 Objective-C 慣例,新增 init 執行個體方法。如果建構函式含有參數,則會使用與執行個體方法相同的命名規則。

新增三個 C 樣式函式:

  • 第一個函式接受新分配的物件做為第一個參數。此函式通常用於呼叫子類別建構函式。並遵循與靜態方法相同的命名規則。(其中「init」是方法名稱)
  • 已新增兩個函式,用於分配及初始化新的物件。這些前置字串以前置字串表示:
    • create_ 函式會傳回自動釋出的物件。
    • new_ 函式會傳回保留的物件。
Java 範例
package com.google;
class Foo {
  Foo() { ... }
  Foo(Object a, Object b) { ... }
}
目標 - C 範例
@interface ComGoogleFoo : NSObject

- (instancetype)init;

- (instancetype)initWithId:(id)a
                    withId:(id)b;

@end

FOUNDATION_EXPORT void ComGoogleFoo_init(ComGoogleFoo *self);

FOUNDATION_EXPORT ComGoogleFoo *new_ComGoogleFoo_init() NS_RETURNS_RETAINED;

FOUNDATION_EXPORT ComGoogleFoo *create_ComGoogleFoo_init();

FOUNDATION_EXPORT void ComGoogleFoo_initWithId_withId_(ComGoogleFoo *self, id a, id b);

FOUNDATION_EXPORT ComGoogleFoo *new_ComGoogleFoo_initWithId_withId_(id a, id b) NS_RETURNS_RETAINED;

FOUNDATION_EXPORT ComGoogleFoo *create_ComGoogleFoo_initWithId_withId_(id a, id b);

欄位

執行個體欄位 (非靜態)

Java 執行個體變數會變成 Objective-C 執行個體變數。名稱與結尾的底線相同。宣告「最終」的原始欄位是一個特殊情況,不會轉譯為執行個體變數。

  • 您可以使用「->」語法直接存取欄位。
  • 原始欄位可直接設定。
    • 最終基元 (常數) 會翻譯為靜態常數。(請參閱靜態欄位)。
  • 非原始欄位必須使用提供的 setter 函式設定:
    • ClassName_set_fieldName_(instance, value)
Java 範例
package com.google;
class Foo {
  public int myInt;
  public String myString;
}
目標 - C 範例
Foo *foo = [[Foo alloc] init];

// Access a primitive field.
i = foo->myInt_;

// Set a primitive field.
foo->myInt_ = 5;

// Access a non-primitive field.
NSString *s = foo->myString_;

// Set a non-primitive field.
ComGoogleFoo_set_myString_(foo, @"bar");

靜態欄位

靜態變數必須使用提供的 getter 和 setter 函式來存取。 這些存取子函式可確保在存取變數之前,已執行類別初始化。

  • 存取靜態欄位
    • ClassName_get_fieldName()
  • 指派 (非最終) 靜態欄位
    • ClassName_set_fieldName()
  • 取得原始靜態欄位的指標。
    • ClassName_getRef_fieldName()
    • 僅適用於非最終和非揮發性欄位。

最終原始欄位 (常數) 可以安全地存取,因為其值不需要取決於類別初始化。

  • ClassName_fieldName
Java 範例
package com.google;
class Foo {
  public static final MY_FINAL_INT = 5;
  public static int myInt;
  public static String myString;
}
目標 - C 範例
// Access a primitive constant field.
jint i = ComGoogleFoo_MY_FINAL_INT;   // No class initialization
i = ComGoogleFoo_get_MY_FINAL_INT();  // Class initialization

// Access a primitive field.
i = ComGoogleFoo_get_myInt();

// Set a primitive field.
ComGoogleFoo_set_myInt(5);

// Access a non-primitive field.
NSString *s = ComGoogleFoo_get_myString();

// Set a non-primitive field.
ComGoogleFoo_set_myString(@"bar");

列舉

J2ObjC 會為每個 Java 列舉產生兩種類型。系統會產生 Objective-C 類別類型,提供 Java 列舉的完整功能。此外,C 列舉會使用 Foundation 架構的 NS_ENUM 巨集來產生。所有產生的 API 都會使用 Objective-C 類別類型。C 列舉可做為轉換陳述式的常數值或儲存類型使用。

產生的列舉類型如下:

  • 以與一般 Java 類別相同的規則為 Objective-C 類別命名。(請參閱類型)
  • C 列舉已命名為一般 Java 類別,並加上「_Enum」後置字串。

列舉常數會像靜態欄位一樣存取。

Java 範例
package com.google;
enum Color {
  RED, GREEN, BLUE
}
Objective-C 標頭範例
typedef NS_ENUM(NSUInteger, ComGoogleColor_Enum) {
  ComGoogleColor_Enum_RED = 0;
  ComGoogleColor_Enum_GREEN = 1;
  ComGoogleColor_Enum_BLUE = 2;
};

@interface ComGoogleColor : JavaLangEnum < NSCopying >
+ (IOSObjectArray *)values;
+ (ComGoogleColor *)valueOfWithNSString:(NSString *)name;
@end

inline ComGoogleColor *ComGoogleColor_get_RED();
inline ComGoogleColor *ComGoogleColor_get_GREEN();
inline ComGoogleColor *ComGoogleColor_get_BLUE();

// Provides conversion from ComGoogleColor_Enum values.
FOUNDATION_EXPORT ComGoogleColor *ComGoogleColor_fromOrdinal(NSUInteger ordinal);