本地方法怎麼映射Java層的數據類型

前言

Java 語言上定義了不一樣的數據類型,好比有基礎類型intdouble等等,還有全部類的父類Object等,這些都是 Java 層面的類型,而使用本地方法的處理過程須要有它們對應的類型。java

大概的流程

Java 層編寫的本地方法,被編譯器編譯爲字節碼,字節碼將按照規範將不一樣類型的參數給記錄到 class 文件中,好比 B 表示 byte、I 表示 int、J 表示 long 等等。那麼一個以下的本地方法,被記錄爲(Ljava/lang/Object;II)V數組

public static native void test(Object o,  int  i, int i2);
複製代碼

上述對應的方法被註冊JVM中,當執行到調用本地方法時則會按照類型映射轉換成本地數據類型,好比int->jintObject->jobject。這裏其實 int 和 jint 在 C++ 中是同樣的,只是用 typedef 定義了另一個名稱而已,而 jobject 是一個指針,執行引擎在執行 Java 層邏輯時生成了 Object 對象,它在 JVM 層有專門的數據結構,這裏的 jobject 就是指向這個結構的指針,在須要使用時能夠強制轉換成 JVM 層的數據結構,而後便可對其進行操做。另外,JVM 中用 oop 來表示對象指針。bash

基礎類型映射

Java Type Native Type value
boolean jboolean true或false
byte jbyte -128~127
short jshort -pow(2,15)~pow(2,15)-1
int jint -pow(2,31)~pow(2,31)-1
long jlong -pow(2,63)~pow(2,63)-1
float jfloat IEEE754標準單精度浮點數
double jdouble IEEE754標準雙精度浮點數
char jchar 16位不帶符號,Unicode字符

引用類型映射

除了基礎的類型映射外,Java 層其餘對象類型爲引用類型,那麼本地方法對應的是 jobject 類型,另外,它還會派生出常常用的一些子類,好比 jstring、jclass 等等,具體以下,數據結構

class _jobject {};
class _jclass : public _jobject {};
class _jthrowable : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jobjectArray : public _jarray {};
複製代碼

能夠看到定義了_jobject類,該類爲空類,而其餘的類包括_jclass _jthrowable _jstring _jarray都是繼承_jobject類。此外,數組類型還派生出了9個子類,分別對應基礎類型數組和引用類型數組。併發

前面定義完類後再定義指針別名,這裏的就是本地方法的類型了。另外,這些都是 C++ 的定義,若是是 C 編譯器則會使用 struct 來定義 _jobject,而非 class。機器學習

typedef _jobject *jobject;
typedef _jclass *jclass;
typedef _jthrowable *jthrowable;
typedef _jstring *jstring;
typedef _jarray *jarray;
typedef _jbooleanArray *jbooleanArray;
typedef _jbyteArray *jbyteArray;
typedef _jcharArray *jcharArray;
typedef _jshortArray *jshortArray;
typedef _jintArray *jintArray;
typedef _jlongArray *jlongArray;
typedef _jfloatArray *jfloatArray;
typedef _jdoubleArray *jdoubleArray;
typedef _jobjectArray *jobjectArray;
複製代碼

CPP的空類

上面的引用類型定義爲空類,這裏瞭解下C++的空類,一般咱們要定義一個空類能夠以下兩種方式,分佈式

class Empty{}
複製代碼
struct Empty{}
複製代碼

通過上述定義後的空類,它的大小爲1,可是一個空類啥都沒有的話它有什麼用呢?其實它能夠用來區分不一樣的對象,空類定義的不一樣對象擁有不一樣的地址,使用new操做出來的對象也有不一樣的指針,並且空類也能區分不一樣的類別。oop

指針轉換

因此有了這些類型映射後咱們是怎麼聯繫起來使用的呢?其實很簡單,答案就是進行指針轉換,前面提到過 Java 層的對象在 JVM 中是有必定的數據結構的,即用 oop 來表示對象指針,那麼 jobject 能夠做以下轉換,其中 handle 即爲 jobject 類型。學習

oop result = *reinterpret_cast<oop*>(handle);
複製代碼

轉換成 oop 後要進一步處理就很方便了,好比想要獲取一些類相關的元數據時可使用其中的 klass 來獲取。ui

總結

以上,Java 層定義的類型在本地方法有着與之相對應的數據類型,並且 Java 層源碼被編譯爲字節碼後保存了本地方法參數對應的類型,JVM 執行時能夠根據不一樣的類型轉換成本地方法對應的類型,而本地方法定義的類型都爲空類,主要做用是用來綁定對象,而且能夠區分對象類型,在必要時刻經過指針轉換便可訪問對象或類元數據。

-------------推薦閱讀------------

個人2017文章彙總——機器學習篇

個人2017文章彙總——Java及中間件

個人2017文章彙總——深度學習篇

個人2017文章彙總——JDK源碼篇

個人2017文章彙總——天然語言處理篇

個人2017文章彙總——Java併發篇

------------------廣告時間----------------

知識星球:遠洋號

公衆號的菜單已分爲「分佈式」、「機器學習」、「深度學習」、「NLP」、「Java深度」、「Java併發核心」、「JDK源碼」、「Tomcat內核」等,可能有一款適合你的胃口。

爲何寫《Tomcat內核設計剖析》

歡迎關注:

這裏寫圖片描述
相關文章
相關標籤/搜索