類型
- 針對原始類型,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);