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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

instanceof java list_Java:Instanceof和泛型

發布時間:2024/9/3 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 instanceof java list_Java:Instanceof和泛型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在查看通用數據結構中的值索引之前,我想看看它是否甚至已被參數化為類型this的實例。

但是當我這樣做時,Eclipse會抱怨:

@Override

public int indexOf(Object arg0) {

if (!(arg0 instanceof E)) {

return -1;

}

這是錯誤消息:

Cannot perform instanceof check against type parameter E. Use instead its erasure Object since generic type information will be erased at runtime

有什么更好的方法呢?

錯誤消息說明了一切。在運行時,該類型已消失,無法對其進行檢查。

您可以通過為對象創建工廠來捕獲它,如下所示:

public static < T > MyObject< T > createMyObject(Class< T > type) {

return new MyObject< T >(type);

}

然后在對象的構造函數中存儲該類型,變量,以便您的方法如下所示:

if (arg0 != null && !(this.type.isAssignableFrom(arg0.getClass()))

{

return -1;

}

我不認為您想要Class.isAssignableFrom。

@Tom,我昨晚是從記憶中寫這本書的,我將其固定為實際上通過了課程(duh!),但否則,我不明白您為什么不想要它(也許今天早上我需要更多咖啡,我只在我的第一杯咖啡上)。

我和湯姆在一起。你能澄清一下嗎?使用isAssignableFrom()將是我的工作選擇。也許我錯過了什么?

@ luis,Toms評論可能意味著我應該使用isInstance()并傳遞實際的arg0參數。它具有避免空檢查的優點。

我有類似的情況,但我無法完全理解答案。你能為像我這樣的假人澄清一下嗎?

@RubensMariuzzo可能有幫助:ralfebert.de/blog/java/isassignablefrom的重要部分是:isAssignableFrom告訴您泛型T是否是實例arg0的超類。

@ Emerald214,您不需要擴展該類,但是該類具有靜態方法(這是靜態工廠模式javaworld.com/javaworld/jw-06-2001/j1-01-sintes2.html)

使用泛型進行運行時類型檢查的兩個選項:

選項1-破壞您的構造函數

假設您要覆蓋indexOf(...),并且只想檢查類型以提高性能,以免自己遍歷整個集合。

創建一個骯臟的構造函數,如下所示:

public MyCollection< T >(Class< T > t) {

this.t = t;

}

然后,您可以使用isAssignableFrom檢查類型。

public int indexOf(Object o) {

if (

o != null &&

!t.isAssignableFrom(o.getClass())

) return -1;

//...

每次實例化對象時,都必須重復一次:

new MyCollection(Apples.class);

您可能會認為這不值得。在ArrayList.indexOf(...)的實現中,它們不檢查類型是否匹配。

選項2-讓它失敗

如果您需要使用需要未知類型的抽象方法,那么您真正想要的只是讓編譯器停止對instanceof的抱怨。如果您有這樣的方法:

protected abstract void abstractMethod(T element);

您可以像這樣使用它:

public int indexOf(Object o) {

try {

abstractMethod((T) o);

} catch (ClassCastException e) {

//...

您正在將對象強制轉換為T(您的泛型類型),只是為了欺騙編譯器。您的強制轉換在運行時不執行任何操作,但是當您嘗試將錯誤類型的對象傳遞給抽象方法時,您仍然會收到ClassCastException。

注意1:如果您在抽象方法中執行其他未經檢查的強制轉換,則ClassCastExceptions將在此處被捕獲。那可能是好事也可能是壞事,因此請仔細考慮。

注意2:使用instanceof時,您將獲得免費的空檢查。由于您無法使用它,因此您可能需要裸手檢查null。

舊帖子,但是做普通instanceOf檢查的一種簡單方法。

public static < T > boolean isInstanceOf(Class< T > clazz, Class< T > targetClass) {

return clazz.isInstance(targetClass);

}

目前尚不清楚您在這里實際做出了什么貢獻。

如果您的類擴展了具有通用參數的類,則您還可以在運行時通過反射來獲取它,然后將其用于比較,即

class YourClass extends SomeOtherClass

{

private Class< ? > clazz;

public Class< ? > getParameterizedClass()

{

if(clazz == null)

{

ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass();

clazz = (Class< ? >)pt.getActualTypeArguments()[0];

}

return clazz;

}

}

在上述情況下,在運行時將從getParameterizedClass()中獲取String.class并進行緩存,因此在進行多次檢查時不會有任何反射開銷。請注意,您可以從ParameterizedType.getActualTypeArguments()方法中通過索引獲取其他參數化類型。

我遇到了同樣的問題,這是我的解決方案(非常謙虛,@ george:這一次編譯并正在工作……)。

我的探針位于實現Observer的抽象類內部。

Observable可以通過Object類觸發update(...)方法,該方法可以是任何種類的Object。

我只想處理T類型的對象

解決方案是將類傳遞給構造函數,以便能夠在運行時比較類型。

public abstract class AbstractOne< T > implements Observer {

private Class< T > tClass;

public AbstractOne(Class< T > clazz) {

tClass = clazz;

}

@Override

public void update(Observable o, Object arg) {

if (tClass.isInstance(arg)) {

// Here I am, arg has the type T

foo((T) arg);

}

}

public abstract foo(T t);

}

對于實現,我們只需要將Class傳遞給構造函數

public class OneImpl extends AbstractOne {

public OneImpl() {

super(Rule.class);

}

@Override

public void foo(Rule t){

}

}

否則您可能會嘗試將E轉換為E失敗,例如

public int indexOf(Object arg0){

try{

E test=(E)arg0;

return doStuff(test);

}catch(ClassCastException e){

return -1;

}

}

+1實用的非工程化解決方案,可輕松進行檢查!我希望我能投票更多

這不會工作。 E在運行時被擦除,因此強制類型轉換不會失敗,您只會收到編譯器警告。

對象的運行時類型是要過濾的相對任意的條件。我建議遠離您的收藏夾。只需將您的集合委托給構造中傳遞的過濾器即可實現。

public interface FilterObject {

boolean isAllowed(Object obj);

}

public class FilterOptimizedList implements List {

private final FilterObject filter;

...

public FilterOptimizedList(FilterObject filter) {

if (filter == null) {

throw NullPointerException();

}

this.filter = filter;

}

...

public int indexOf(Object obj) {

if (!filter.isAllows(obj)) {

return -1;

}

...

}

...

}

final List longStrs = new FilterOptimizedList(

new FilterObject() { public boolean isAllowed(Object obj) {

if (obj == null) {

return true;

} else if (obj instanceof String) {

String str = (String)str;

return str.length() > = 4;

} else {

return false;

}

}}

);

(盡管如果您使用的是Comparator或類似版本,則可能要檢查實例類型。)

從技術上講,您不必這樣做,這就是泛型的重點,因此您可以進行編譯類型檢查:

public int indexOf(E arg0) {

...

}

但是如果您有一個類層次結構,那么@Override可能是一個問題。否則,請參見Yishai的答案。

是的,List接口要求該函數采用對象參數。

您實施清單?為什么不實施List ?

(例如,參見ArrayList的聲明:java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html)

@Rosarch:List接口的indexOf()方法不需要給定的參數與您要查找的對象具有相同的類型。它只是必須等于.equals(),并且不同類型的對象可以彼此等于.equals()。這與remove()方法的問題相同,請參見:stackoverflow.com/questions/104799/

[[[sheepishly]]]沒關系,我認為indexOf()要求E作為參數而不是Object。 (他們為什么這樣做?!?!)

@Jason基本上是因為它會破壞不需要有效類型轉換的完全有效的代碼。另外,由于泛型不是協變的,因此即使使用indexOf()實際上返回一個實數索引(對象),您也會陷入一些帶有類型參數的極端情況(例如,列表本身具有類型參數的列表)在列表中,但編譯器無法讓您看到它)。

總結

以上是生活随笔為你收集整理的instanceof java list_Java:Instanceof和泛型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。