隨趣科技有限公司
隨趣科技有限公司虛擬人技術(shù)傳播者

公司成立于2021年,是全球范圍內(nèi)少數(shù)同時(shí)擁有全棧3D AIGC技術(shù)和自然語言生成式大模型技術(shù)的前沿人工智能公司。

󦌑136?2108?0965

󦘑136 2108 0965

󦗑1039900924

󦌡1039900924@qq.com

虛擬人類學(xué)方法,虛擬人技術(shù)可用于

2022-08-19316

1、Java中的虛擬方法virtual method是什么含義

   Java方法調(diào)用的虛分派

JUN | COMMENTS

本文通過介紹 Java 方法調(diào)用的虛分派,來加深對 Java 多態(tài)實(shí)現(xiàn)的理解。需要預(yù)先理解 Java 字節(jié)碼和 JM 的基本框架。

虛分配(irtual Dispatch)

首先從字節(jié)碼中對方法的調(diào)用說起。Java 的 bytecode 中方法的調(diào)用實(shí)現(xiàn)分為四種指令:

為最常見的情況,包含 virtual dispatch 機(jī)制;

是作為對 private 和構(gòu)造方法的調(diào)用,繞過了 virtual dispatch;

的實(shí)現(xiàn)跟 invokevirtual 類似。

是對靜態(tài)方法的調(diào)用。

其中最復(fù)雜的要屬 invokevirtual 指令,它涉及到了多態(tài)的特性,使用 virtual dispatch 做方法調(diào)用。

virtual dispatch 機(jī)制會首先從 receiver(被調(diào)用方法的對象)的類的實(shí)現(xiàn)中查找對應(yīng)的方法,如果沒找到,則去父類查找,直到找到函數(shù)并實(shí)現(xiàn)調(diào)用,而不是依賴于引用的類型。

下面是一段有趣的代碼。反映了 virtual dispatch 機(jī)制 和 一般的 field 訪問的不同。

public class Greeting {

String intro = "Hello";

String target(){

return "world";

}

}

public class FrenchGreeting extends Greeting {

String intro = "Bonjour";

String target(){

return "le monde";

}

public static void main(String[] args){

Greeting english = new Greeting();

Greeting french = new FrenchGreeting();

( "," ());

( "," ());

(((FrenchGreeting)french).intro "," ((FrenchGreeting)french).target());

}

}

運(yùn)行的結(jié)果為

Hello,world

Hello,le monde

Bonjour,le monde

前兩行輸出中,對于 intro 這個(gè)屬性的訪問,直接指向了父類中的變量,因?yàn)橐妙愋蜑楦割悺?/p>

第二行對于 target()的方法調(diào)用,則是指向了子類中的方法,雖然引用類型也為父類,但這是虛分派的結(jié)果,虛分派不管引用類型的,只查被調(diào)用對象的類型。

既然虛分派機(jī)制是從被調(diào)用對象本身的類開始查找,那么對于一個(gè)覆蓋了父類中某方法的子類的對象,是無法調(diào)用父類中那個(gè)被覆蓋的方法的嗎?

在虛分派機(jī)制中這確實(shí)是不可以的。但卻可以通過 invokespecial 實(shí)現(xiàn)。如下代碼

public class FrenchGreeting extends Greeting {

String intro = "Bonjour";

String target(){

return "le monde";

}

public String func(){

return ();

}

public static void main(String[] args){

Greeting english = new Greeting();

FrenchGreeting french = new FrenchGreeting();

(());

}

}

func()就成功的調(diào)用了父類的方法 target(),雖然 target()已經(jīng)被子類重寫了。具體的調(diào)用細(xì)節(jié),從字節(jié)碼中可以看到:

ALOAD 0: this

INOKESPECIAL () : String

ARETURN

其中使用了 invokespecial 指令,而不是施行虛分派策略的 invokevirtual 指令。

方法表(Method Table)

介紹了虛分派,接下來介紹是它的一種實(shí)現(xiàn)方式 – 方法表。類似于 C的虛函數(shù)表 vtbl。

在有的 JM 實(shí)現(xiàn)中,使用了方法表機(jī)制實(shí)現(xiàn)虛分派,而有時(shí)候,為了節(jié)省內(nèi)存可能不采用方法表的實(shí)現(xiàn)。

不要被方法表這個(gè)名字迷惑,它并不是記錄所有方法的表。它是為虛分派,不會記錄用 invokestatic 調(diào)用的靜態(tài)方法和用 invokespecial 調(diào)用的構(gòu)造函數(shù)和有方法。

JM 會在鏈接類的過程中,給類分配相應(yīng)的方法表內(nèi)存空間。每個(gè)類對應(yīng)一個(gè)方法表。這些都是存在于 method area 區(qū)中的。這里與 C略有不同,C中每個(gè)對象的第一個(gè)指針就是指向了相應(yīng)的虛函數(shù)表。而 Java 中每個(gè)對象索引到對應(yīng)的類,在對應(yīng)的類數(shù)據(jù)中對應(yīng)一個(gè)方法表。(關(guān)于鏈接的更多信息,參見博文《Java 類的裝載、鏈接和初始化》)

一種方法表的實(shí)現(xiàn)如下:

父類的方法比子類的方法先得到解析,即父類的方法相比子類的方法位于表的前列。

表中每項(xiàng)對應(yīng)于一個(gè)方法,索引到實(shí)際方法的實(shí)現(xiàn)代碼上。如果子類重寫了父類中某個(gè)方法的代碼,則該方法第一次出現(xiàn)的位置的索引更換到子類的實(shí)現(xiàn)代碼上,而不會在方法表中出現(xiàn)新的項(xiàng)。

JM 運(yùn)行時(shí),當(dāng)代碼索引到一個(gè)方法時(shí),是根據(jù)它在方法表中的偏移量來實(shí)現(xiàn)訪問的。(第一次執(zhí)行到調(diào)用指令時(shí),會執(zhí)行解析,將符索引替換為對應(yīng)的直接索引)。

由于 invokevirtual 調(diào)用的方法在對應(yīng)的類的方法表中都有固定的位置,直接索引的值可以用偏移量來表示。(符索引解析的最終目的是完成直接索引:對象方法和對象變量的調(diào)用都是用偏移量來表示直接索引的)

invokeinterface 與 invokevirtual 的比較

當(dāng)使用 invokeinterface 來調(diào)用方法時(shí),由于不同的類可以實(shí)現(xiàn)同一 interface,我們無法確定在某個(gè)類中的 inteface 中的方法處在哪個(gè)位置。于是,也就無法解析 CONSTANT_intefaceMethodrefinfo 為直接索引,而必須每次都執(zhí)行一次在 methodtable 中的搜索了。 所以,在這種實(shí)現(xiàn)中,通過 invokeinterface 訪問方法比通過 invokevirtual 訪問明顯慢很多。

參考:

irtual Dispatch

首先從字節(jié)碼中對方法的調(diào)用說起。

java的bytecode中對方法的調(diào)用實(shí)現(xiàn)分為四種情況:

為最常見的情況,包含virtual dispatch機(jī)制;

,繞過了virtual dispatch;

。

其中最復(fù)雜的要屬 invokevirtual .

virtual dispatch機(jī)制會首先從 receiver(調(diào)用該方法的對象)的類的實(shí)現(xiàn)中查找對應(yīng)的方法,如果沒找到,則去父類查找,直到找到函數(shù)并實(shí)現(xiàn)調(diào)用,而不是依賴于引用類型。

下面是一段有趣的代碼。反映了virtual dispatch機(jī)制 和 一般的field訪問的不同。

public class Greeting {

String intro = "Hello";

String target(){

return "world";

}

}

public class FrenchGreeting extends Greeting {

String intro = "Bonjour";

String target(){

return "le monde";

}

public static void main(String[] args){

Greeting english = new Greeting();

Greeting french = new FrenchGreeting();

( "," ());

( "," ());

(((FrenchGreeting)french).intro "," ((FrenchGreeting)french).target());

}

}

運(yùn)行的結(jié)果為

Hello,world

Hello,le monde

Bonjour,le monde

其中的第二行是亮點(diǎn)。

對于intro這個(gè)filed的訪問,直接指向了父類中的變量,因?yàn)橐?類型為父類。

而對于target的方法調(diào)用,則是指向了子類中的方法,雖然引用類型也為父類,但這是virtual dispatch的結(jié)果,virtual dispatch不管引用類型的,只查receiver的類型。

既然 虛分派 機(jī)制是從receiver對象的子類開始查找,由此看來,對于一個(gè)覆蓋了父類中某方法的子類的對象,是無法調(diào)用父類中那個(gè)被覆蓋的方法的嗎?

在虛分派機(jī)制中這確實(shí)是不可以的。但卻可以通過invokespecial實(shí)現(xiàn)。如下代碼

public class FrenchGreeting extends Greeting {

String intro = "Bonjour";

String target(){

return "le monde";

}

public String func(){

return ();

}

public static void main(String[] args){

Greeting english = new Greeting();

FrenchGreeting french = new FrenchGreeting();

(());

}

}

func()就成功的調(diào)用了父類的方法target,雖然target已經(jīng)被子類重寫了。怎么實(shí)現(xiàn)的?讓我們看一看func方法中生成的字節(jié)碼:

ALOAD 0: this

INOKESPECIAL () : String

ARETURN

原來如此,它是通過invokespecial 指令來調(diào)用的。

如果刪除jump那一段 程序可以正常運(yùn)行,請問jump那段有什么問題??

C里才叫虛類。

Java里應(yīng)該稱為抽象類,類名前加abstract,不能夠?qū)嵗?。與接口不同的是:

1、一個(gè)子類只能繼承一個(gè)抽象類,但能實(shí)現(xiàn)多個(gè)接口;

2、一個(gè)抽象類可以有構(gòu)造方法,接口沒有構(gòu)造方法;

3、一個(gè)抽象類中的方法不一定是抽象方法,即其中的方法可以有實(shí)現(xiàn)(有方法體),接口中的方法都是抽象方法,不能有方法體,只有聲明;

4、一個(gè)抽象類可以是public、private、protected、default,

接口只有public;

5、一個(gè)抽象類中的方法可以是public、private、protected、default,

接口中的方法只能是public和default。

虛擬人類學(xué)方法,虛擬人技術(shù)可用于  第1張

2、人類學(xué)最根本的研究方法是問卷法嗎

   文化人類學(xué)的主要研究方法有:

田野調(diào)查法也稱為田野工作,是一種對一個(gè)社會及其生活方式親身從事的長期性的調(diào)查和體會工作。

這是文化人類學(xué)最有特色的研究法。文化人類學(xué)家特別注重通過直接的觀察,收集每一手證據(jù)。

采用這種方法,人們在選擇研究一種人類行為時(shí),必須全面考察與之相關(guān)聯(lián)的問題。

比較法在文化人類學(xué)的研究中無時(shí)無刻不在使用。

概念分析法即構(gòu)建一個(gè)或若干個(gè)概念以分析各種社會文化現(xiàn)象。它首先從個(gè)別文化的經(jīng)驗(yàn)材料中歸納出一般原則,然后把它作為分析文化的工具,以分析其他文化現(xiàn)象。

你的文獻(xiàn)綜述具體準(zhǔn)備往哪個(gè)方向?qū)?,題目老師同意了沒,具體有要要,需要多少字呢? 你可以告訴我具體的排版格式要,文獻(xiàn)綜述想寫好,先要在圖書館找好相關(guān)資料,確定好題目與寫作方向。老師同意后在下筆,還有什么不了解的可以直接問我,...

人類學(xué)是社會科學(xué),因此需要開展調(diào)查研究,可以參考如下資料: 人類學(xué)研究的基本方法是田野民族志,也就是深入實(shí)地進(jìn)行調(diào)查。

虛擬人類學(xué)方法,虛擬人技術(shù)可用于  第2張