Java中子类和集合之间的类转换异常问题

时间:2016-03-22 15:54:54

标签: java generics collections casting

所以,我有以下两个类:

Class A { }
Class B extends A { }
Class C extends A { }

以下方法:

public void foo(Collection<A> bar) {
    List<A> listA = new ArrayList<>();

    for(A a : bar) {
        //a and anotherA are both of the same subtype of A
        A anotherA = getAnotherA(a);
        listA.add(anotherA);
    }

    bar.clear();
    bar.addAll(listA);
}

现在,我试图以两种不同的方式调用此方法,但我无法使该转换正常工作...希望我只是忽略了一些小事。

所以,以下是我称之为的两种方式:

方式1:

A obj = ...;
Field field = //get field representing a collection of sub-type of A
Collection<A> collection = field.get(...);
foo(collection);

方式2:

B obj = ...;
Set<C> setOfC = b.getSetOfC();
foo(setOfC);

我尝试过很多次尝试,但我似乎无法编译!例如,在方式2中,我尝试将setOfC转换为Set<A>,但我得到了一个类强制转换异常。我试图将bar转换为Collection<? extends A>,但是bar.addAll(..)失败了。我试图向foo添加泛型,但也会出错。在方式1中,我也尝试将collection投射到Collection<? extends A>,但仍然没有运气。

2 个答案:

答案 0 :(得分:3)

即使Set<C>Collection<A>,即使SetCollection,您也无法将C传递给期望A的方法foo,因为Java的泛型是不变的。

您可以在A方法上引入一个类型参数,其上限为A。然后,您可以在整个方法中使用type参数。这将确保使用相同的public static <T extends A> void foo(Collection<T> bar) { List<T> listA = new ArrayList<>(); for(T a : bar) { //a and anotherA are both of the same subtype of A T anotherA = getAnotherA(a); listA.add(anotherA); } bar.clear(); bar.addAll(listA); } 子类型。

a

您的评论似乎表明anotherAgetAnotherA属于同一类型,因此应该为您编译。如果没有,那么C方法将需要一些工作,以便传入C将返回A而不是func getJson(word: String){ let url: NSURL = NSURL(string: "MyPHP.php")! let session = NSURLSession.sharedSession() let request:NSMutableURLRequest = NSMutableURLRequest(URL:url) request.HTTPMethod = "POST" request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData let bodydata = "label=\(word)" request.HTTPBody = bodydata.dataUsingEncoding(NSUTF8StringEncoding) if bodydata != " " { let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in let httpResponse = response as! NSHTTPURLResponse let statusCode = httpResponse.statusCode if(statusCode == 200) { self.libraryArray.removeAll() do{ let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments) print(json) if let book = json["Book"] as? [[String: AnyObject]]{ for books in book { if let BookName = book["Name"] as? [String: AnyObject] { let name = BookName["name"] as? String let author = BookName["author"] as? String let bookDict = [ "name": name, "id": id, "author": author] self.libraryArray.append(bookDict) self.tableView.reloadData() // has 14- 20 seconds delay, but the JSON has already received } } } }catch { print("error:\(error)") } self.tableView.reloadData() // <<----- HERE } } task.resume() // self.tableView.reloadData() if i try to reload here, it will not be executed. } } @IBAction func Next(sender: AnyObject) { self.getJson("someString") //self.tableView.reloadData() if i try to reload here, it will be fail. }

答案 1 :(得分:0)

如果你有这个课程:

Class YourA { }
Class YourB extends YourA { }
Class YourC extends YourA { }

你方法的签名最像是

public <G extends YourA> void foo(Collection<G> bar) {...}