java object強制類型轉換_scala?object?轉Class?Scala強制類型轉換

asInstanceOf[T]

將對象類型強制轉換為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三個預定義方法分析

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

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

先上代碼

PredefineTest.scala

Scala代碼?a4c26d1e5885305701be709a3d33442f.png

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方法體內代碼的抽象語法樹(AST)信息如下:

Scala代碼?a4c26d1e5885305701be709a3d33442f.png

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反編譯工具查看對應代碼如下:

Java代碼?a4c26d1e5885305701be709a3d33442f.png

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;

結合上面源碼來進行分析

classOf[T]

獲取類型T的Class對象

classOf方法定義在scala.Predef object:

Scala代碼?a4c26d1e5885305701be709a3d33442f.png

object?Predef?extends?LowPriorityImplicits?{

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

...

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

Predef

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

isInstanceOf[T]

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

isInstanceOf和asInstanceOf

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

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

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

特別注意的是?Any 和AnyRef

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

再看一下例子:

Scala代碼?a4c26d1e5885305701be709a3d33442f.png

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]

將對象類型強制轉換為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, 這種用法

已經被編譯器禁止了:

scala> new AnyRef().isInstanceOf[AnyVal]

:8: error: type AnyVal

cannot be used in a type pattern or isInstanceOf test

new AnyRef().isInstanceOf[AnyVal]

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

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

Scala會將其轉換為調用相應的toT方法, 如 1.asInstanceOf[Char], 就會轉換為 97.toChar,

其中toChar 定義在 scala.Int:

Scala代碼?a4c26d1e5885305701be709a3d33442f.png

final?class?Int?extends?AnyVal?{

...

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

...

}

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

結論

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

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

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

值得探討的地方

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

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

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383004.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383004.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383004.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java毛玻璃_模糊效果(毛玻璃效果)

模糊效果(毛玻璃效果)效果演示:1. 使用iOS自帶的 UIImageImageEffects 文件文件中有這么幾個方法:- (UIImage *)applyLightEffect;- (UIImage *)applyExtraLightEffect;- (UIImage *)applyDarkEffect;- (UIImage *)applyTintEffectWithColor:(UIColor *)…

java程序崩潰怎么重啟_android 異常崩潰后 重啟app(進程守護方式實現)

【實例簡介】【實例截圖】【核心代碼】package com.sunfusheng.daemon.sample;import android.content.ComponentName;import android.content.Intent;import android.os.Looper;import android.util.Log;import com.blankj.utilcode.util.AppUtils;import com.sunfusheng.daem…

mysql 存儲過程 循環結構 命名_mysql存儲過程----循環結構

循環結構一共分為三種:三種循環結構分別為while、repeat、loop。while循環語法while 表達式(如果表達式為true則執行業務邏輯,否則不執行,與repeat循環相反,repeat循環滿足表達式退出循環,不滿足一直執行) do業務邏輯e…

mysql 組合索引 or_Mysql_組合索引和單列索引

一、目標什么時候使用組合索引,什么時候使用單獨索引組合索引、單獨索引區別組合索引:最左前綴匹配原則二、前期數據準備1. 建表CREATE TABLE user (uidint(11) NOT NULLAUTO_INCREMENT,namevarchar(50) DEFAULT NULL,pwdvarchar(50) DEFAULT NULL,creat…

mysql與mangodb多租戶_MongoDB多租戶(Java):如何使用MongoClient在運行時切換具有不同數據庫憑據的MongoDB數據庫?...

我正面臨一個關于MongoDB多租戶的問題.我有兩個不同的mongoDB數據庫(db1和db2).這兩者都有不同的憑據.db1憑據:userName:admin密碼:passwddb2憑據:userName:admin1密碼:passwd1我需要在運行時從一個數據庫切…

python 庫 全局變量_python局部變量和全局變量global

當你在函數定義內聲明變量的時候,它們與函數外具有相同名稱的其他變量沒有任何關系,即變量名稱對于函數來說是 局部 的。這稱為變量的 作用域 。所有變量的作用域是它們被定義的塊,從它們的名稱被定義的那點開始。使用局部變量例7.3 使用局部…

java 自省_自知 自省 自立 自信 自尊 自治 自強 自制

自知 自省 自立 自信 自尊 自治 自強 自制能知人者有智力,能自知才是真正的智者;能戰勝別人者有力量,能戰勝自己才是真正的強者;能知足者就是富有,能勤奮頑強堅持才是真正的有志者;不失其立足之地的人可以長…

java中json重復數據結構_JAVA把各種數據結構轉換為JSON格式

Java代碼import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import net.sf…

字節字符區別Java_【JAVA基礎】字符數組與字節數組的區別

String.getBytes()和String.tocharArray(),字節數組和字符數組的區別String.getBytes()是將字符串轉化為一個字節數組。而String.toCharArray()是將一個字符串轉化為一個字符數組。【例如】byte bys[] “國慶60周年”.getBytes();char chs[]“國慶60周年”.toCharAr…

mysql日志管理_關于MySQL的日志管理(binlog)

關于MySQL的日志管理(binlog)一、查看binlog的啟用狀態最常用的mysql版本是5.7,默認不開啟binlog,可以在登錄mysql之后,利用以下命令查看當前的binlog啟用狀態:mysql show variables like "%log_bin%";圖中顯示“ON”&a…

java精確測量文本高度_基于文本精確計算UITableViewCell的高度

我正在開發一個ios應用程序,并使用autolayout我正在嘗試創建一個具有不同行高的表視圖 .原型單元的布局如下:我有一個主單元格(黑色)里面有一個UIView(紅色),里面有一個UILabel(藍色)我添加的Autolayout約束如圖所示:The UIView h…

php做一個微信退款,PHP實現微信退款功能

大家好,我是小編,最近在調微信退款接口,發現有許多坑,更大家分享一下① 要是在測試的時候,網頁提示 curl 58 說明 證書的路徑出現問題(這里要填物理路徑,也就是絕對路徑)②網頁提示curl 52 說明你的證書引入…

php顯示時間,php實現用已經過去多長時間的方式顯示時間

本文實例講述了php用已經過去多長時間的方式顯示時間的方法。分享給大家供大家參考。具體如下:這里以一種可讀性比較好的方式顯示已經過去多長時間,比如:距離現在10秒,距離現在1天等等。function time_is_older_than($t, $check_t…

java中日期計算時間差,java中依據,兩個日期,計算時間差

java中根據,兩個日期,計算時間差。分別獲取兩個時間的毫秒數Date.getTime(),相減,得到的值/1000為秒數,/60*1000為分鐘數,/60*60*1000為小時數。/*** 計算時間差** param begin* param end* return*/public…

php獲取token失敗,微信開發,老是獲取token失敗

微信開發,總是獲取token失敗$appid wx1aabc8673b8f103a;$appsecret 9aa99fc9db9bf1321c1afe05feb29b6c;$url "https://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credential&appid$appid&secret$appsecret";$urlhttps://api.weixin.…

2008下php上傳文件崩潰,php – 當用戶反復嘗試上傳無效文件類型時,網站崩潰

我試圖理解錯誤……我有一個允許用戶上傳CSV的網絡應用程序.如果文件類型不是CSV,則不會發生任何操作,頁面只顯示“無效的文件類型”.如果用戶嘗試上載無效的文件類型并反復單擊觸發處理上載的PHP文件的按鈕,則PHP文件最終會無響應,并且網站崩潰時出現以下錯誤:&quo…

java錯誤1601解決方法,求助解決錯誤

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610)at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590)at …

java == hashcode,java中==和equals和hashCode的區別

java中和equals和hashCode的區別 的作用:基本類型:比較的就是值是否相同引用類型:比較的就是地址值是否相同(確切的說,是堆內存地址)equals 的作用:引用類型:默認情況下,比較的是地址值。public boolean eq…

java經典設計模式4,JAVA設計模式(4) 之裝飾設計模式

在現實生活中我們的汽車都具備跑的功能,我們可以不改變汽車原有功能的前提下,把它放入一個裝修廠,開進去讓里面給咱們的車子做一些裝飾,開出來之后呢,就具備了上天的功能了(技術可達是可以的哈),這就給原來…

java讀取gxk文件,Java中常見的IO流及其使用

Java中IO流分成兩大類,一種是輸入流,所有的輸入流都直接或間接繼承自InputStream抽象類,輸入流作為數據的來源,我們可以通過輸入流的read方法讀取字節數據;另一種是輸出流,所有的輸出流都直接或間接繼承自O…