翻譯參考資料

類型

  • 針對原始型別,J2ObjC 已定義 JNI 樣式的 typedefs。
  • 以一般類別型別來說,套件會採駝峰式大小寫形式,並在類別名稱前面加上。
  • 如果是基本物件類型和所有類型變數,則「id」
  • 幾個核心 Java 類型會對應至基礎類型。(例如:將字串變更為 NSString)
  • 對於宣告為「volatile」的欄位,J2ObjC 有更多使用 C11 _Atomic(...) 型別的 typedef 。
  • 如果是內部類型,內部類別名稱會加在外部類別名稱後方,並加上底線。
Java 類型 Objective-C 類型 Objective-C 易變類型
布林值 j 布林 volatile_jboolean
char 吉克 volatile_jchar
位元組 Jbyte volatile_jbyte
short Jshort volatile_jshort
int jint volatile_jint
long jlong volatile_jlong
float jfloat volatile_jfloat
雙精準數 Jdouble volatile_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 NSCopying* volatile_id
foo.bar.Mumble FooBarMumble* volatile_id
foo.bar.Mumber$Inner FooBarMumble_Inner* volatile_id

方法

Objective-C 方法與 Java 方法有兩大差異。它們的語法 將參數嵌入方法選取器的各個元件之間目標-C 方法都不支援超載只要將 參數類型新增至產生的選取器中。此為必要步驟,以免名稱發生衝突 超載 Java 方法

產生的 API 有三種不同方式:執行個體方法、靜態 方法和建構函式執行個體方法會轉譯為 Objective-C 執行個體方法。靜態 方法和建構函式會轉譯為 C 型函式,但也會將 Objective-C 包裝函式 為 Objective-C 開發人員提供更熟悉的 API

實例方法

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

  • 零參數方法未變更
  • 一或多個參數使用下列模式:
    • <java name>With<1st param keyword>:with<2nd param keyword>:with<3rd param keyword>:
  • 參數關鍵字規則:
    • 如果是基本型別,關鍵字是 Java 原始的大寫名稱。(例如:「字元」)
    • 若為非原始類型,關鍵字為駝峰式大小寫的完整類型名稱。(例如:「ComGoogleFoo」
    • 如果是陣列類型,請提供「陣列」會附加至元素類型的關鍵字。
Java 範例
interface Foo {
  void bar();
  String bar(int i);
  java.util.List bar(String s, long[] l);
}
Objective-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) { ... }
}
Objective-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) { ... }
}
Objective-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;
}
Objective-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;
}
Objective-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 列舉 架構的 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);