日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java object强制类型转换_scala object 转Class Scala强制类型转换

發(fā)布時間:2023/11/30 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java object强制类型转换_scala object 转Class Scala强制类型转换 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

asInstanceOf[T]

將對象類型強制轉(zhuǎn)換為T類型。

還是由于泛型存在類型擦除的原因,1.asInstanceOf[String]在運行時會拋出ClassCastException異常,而List(1).asInstanceOf[List[String]]將不會。

packageresti.web

importorg.springframework.beans.factory.annotation.Autowired

importorg.springframework.security.core.context.SecurityContextHolder

importorg.springframework.stereotype.Controller

importorg.springframework.ui.Model

importorg.springframework.web.bind.annotation.RequestMapping

importresti.domain.HttpApi

importresti.service.HttpApiRepository

importorg.springframework.security.core.userdetails.UserDetails

importorg.springframework.web.bind.annotation.RequestMethod

@Controller

@RequestMapping(Array("/product"))

classProductController?@Autowired()?(privatevalhttpApiRepository:?HttpApiRepository)?{

@RequestMapping(method?=?Array(RequestMethod.GET))

def?list(model:?Model)?=?{

//?get?current?user

val?userDetails?=?SecurityContextHolder.getContext().getAuthentication().getPrincipal().asInstanceOf[UserDetails]

model.addAttribute("currentUser",?userDetails.getUsername)

model.addAttribute("products",?httpApiRepository.findProducts())

"product/list"

}

}

classOf、isInstanceOf、asInstanceOf三個預(yù)定義方法分析

Scala的三個預(yù)定義(predefined)方法,我們經(jīng)常用到;它們用來感覺很簡單,

但是里面還是隱藏了一些細節(jié)東西,不妨花點時間來分析分析。

先上代碼

PredefineTest.scala

Scala代碼?

object?PredefineTest{

def?main(args:?Array[String]):Unit?=?{

val?c?:?Char?=?97.asInstanceOf[Char]

"hello".asInstanceOf[String]

1.asInstanceOf[Long]

val?it:?Seq[String]?=?List("a",?"b")

it.asInstanceOf[List[String]]

"hello".isInstanceOf[String]

classOf[String]

}

}

使用scalac?-Xprint:cleanup?PredefineTest.scala,Scala編譯器輸出的main方法體內(nèi)代碼的抽象語法樹(AST)信息如下:

Scala代碼?

val?c:?Char?=?97.toChar();

("hello":?java.lang.String);

1.toLong();

val?it:?Seq?=?immutable.this.List.apply(scala.this.Predef.wrapRefArray(Array[java.lang.String]{"a",?"b"}.$asInstanceOf[Array[java.lang.Object]]()));

it.$asInstanceOf[List]();

"hello".$isInstanceOf[java.lang.String]();

{

classOf[java.lang.String];

()

}

使用jd反編譯工具查看對應(yīng)代碼如下:

Java代碼?

char?c?=?(char)97;

"hello";

1;

Seq?it?=?List..MODULE$.apply(Predef..MODULE$.wrapRefArray((Object[])new?String[]?{?"a",?"b"?}));

((List)it);

("hello"?instanceof?String);

String.class;

結(jié)合上面源碼來進行分析

classOf[T]

獲取類型T的Class對象

classOf方法定義在scala.Predef object:

Scala代碼?

object?Predef?extends?LowPriorityImplicits?{

def?classOf[T]:?Class[T]?=?null

...

classOf的注釋翻譯過來的意思是:返回類型的運行時呈現(xiàn)狀態(tài)。這是一個存根方法。實際的實現(xiàn)是由編譯器填補(自動生成)。

Predef

object是默認導(dǎo)入的,所以classOf方法相當于一個全局方法。

isInstanceOf[T]

判斷對象是否為T類型的實例。

isInstanceOf和asInstanceOf

由scala.Any類定義,Scala類層級的根類;其中class scala.AnyRef

繼承自Any,是所有應(yīng)引用類型的基類;trait scala.AnyVal

也繼承自Any,是所有基本類型的實現(xiàn)的trait。所以所有對象都自動擁有isInstanceOf和asInstanceOf這兩個方法。

特別注意的是?Any 和AnyRef

這兩個類屬于“編譯時類型”(虛擬類型?),不存在于運行時。所以這兩者在Scala中都未提供源碼,其語義由編譯器在編譯時構(gòu)建。

再看一下例子:

Scala代碼?

scala>?1.isInstanceOf[String]

res0:?false

scala>?List(1).isInstanceOf[List[String]]

res0:?true

由于Scala像Java一樣泛型存在類型擦除的原因,List(1).isInstanceOf[List[String]]及相當于List(1).isInstanceOf[List[_]],

List(1) 是List的實例.

asInstanceOf[T]

將對象類型強制轉(zhuǎn)換為T類型。

還是由于泛型存在類型擦除的原因,1.asInstanceOf[String]在運行時會拋出ClassCastException異常,而List(1).asInstanceOf[List[String]]將不會。

在scala 討論組里有人問道這樣一個問題:

”I expect "new AnyRef().isInstanceOf[AnyVal]" to be false, but I

get true instead“

scala> new AnyRef().isInstanceOf[AnyVal]

res0: Boolean = true

大家有興趣看以看看后面的解答,不過試了scala 2.9, 這種用法

已經(jīng)被編譯器禁止了:

scala> new AnyRef().isInstanceOf[AnyVal]

:8: error: type AnyVal

cannot be used in a type pattern or isInstanceOf test

new AnyRef().isInstanceOf[AnyVal]

還有,值得提一下的一個小細節(jié)就是,通過觀察編譯輸出的AST,

知道對于在基本類型如Int等的對象上調(diào)用asInstanceOf[T],

Scala會將其轉(zhuǎn)換為調(diào)用相應(yīng)的toT方法, 如 1.asInstanceOf[Char], 就會轉(zhuǎn)換為 97.toChar,

其中toChar 定義在 scala.Int:

Scala代碼?

final?class?Int?extends?AnyVal?{

...

def?toChar:?Char?=?sys.error("stub")

...

}

而后, Scala編譯器會進一步將其編譯成與“(char)97”相同的字節(jié)碼。

結(jié)論

總而言之,我們把classOf[T]看成Java里的T.class,

obj.isInstanceOf[T]看成 obj instanceof T,

obj.asInstanceOf[T]看成(T)obj就對了。scala為我們提供了語法糖,但也免不了類型擦除問題的影響。

值得探討的地方

個人感覺,Scala對Java的類這一塊沒什么增強,

比如像Ruby一樣類文字量也是對象(雖然理解起來有點繞,但是更能體現(xiàn)面向?qū)ο笠恢滦?,就不用classOf[T]這樣添足的寫法,而是:object.getClass

== String 。如此,是不是JVM的限制,還是Scala目前的關(guān)注點不在此?

總結(jié)

以上是生活随笔為你收集整理的java object强制类型转换_scala object 转Class Scala强制类型转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。