2011-02-06 48 views
13

Mã của tôi không thể chuyển đổi từ E sang E. Tôi có thể tạo một kiểu để nhập E nhưng có vẻ như không cần thiết ở giai đoạn này. Mảng của tôi đã được khai báo là kiểu E. Java Generics, Không thể chuyển đổi từ E sang E

import java.util.Iterator; 

public class DataTypeDemo<E> 
{ 
private E[] data = (E[]) new Object [10]; 

public MyIterator newIterator() 
{ 
    return new MyIterator(); 
} 

private class MyIterator<E> implements Iterator<E> 
{ 
    private int location; 

    public boolean hasNext() 
    { 
     return location < data.length; 
    } 

    public E next() 
    { 
     return (data[location++]); // error here 
    } 

    public void remove() 
    { 
     throw new UnsupportedOperationException(); 
    } 
} 
} 

Compiler, ném lỗi này:

DataTypeDemo.java:23: loại không tương thích tìm thấy: E yêu cầu: E

+1

Vui lòng đăng một ví dụ hoàn chỉnh cho phép người khác tạo lại lỗi của bạn. Nếu không, bạn sẽ không nhận được sự giúp đỡ. BTW, bạn có kiểm tra xem bạn không có hai lớp được gọi là "E" (trong các gói khác nhau) không? – sleske

+0

Bất kỳ lý do nào bạn không sử dụng 'Danh sách '? Mảng và generics thực sự không chơi rất độc đáo với nhau. –

+0

@sleske: 'E' là tham số kiểu trên lớp. Không có lớp thực tế nào được gọi là 'E' trong trường hợp này. –

Trả lời

19

loại bên trong của bạn giới thiệu đó là loại biến riêng:

private class MyIterator<E /* this is the problem*/> implements Iterator<E> 

Và do đó sẽ ghi đè lớp bên ngoài gõ biến

Thay đổi khai báo kiểu của bạn như thế này:

private class MyIterator implements Iterator<E> 

tham khảo:

  • Generics FAQ (mặc dù vấn đề này không được đề cập theo nghĩa đen, nó được ngụ ý bởi FAQ cụm từ này)
5

Gốc của sự cố của bạn là nội dung bên trong lớp của bạn. Đối với trình biên dịch, không có gì đảm bảo rằng hai E có cùng loại.

import java.util.Iterator; 
import java.util.ArrayList; 


    public class DataTypeDemo<E> 
    { 
     private ArrayList<E> data = new ArrayList<E>(10); 

     private class MyIterator implements Iterator<E> 
     { 
      private int location; 

      public boolean hasNext() 
      { 
       return location < data.size(); 
      } 

      public E next() 
      { 
       return data.get(location++); 
      } 

      public void remove() 
      { 
       throw new UnsupportedOperationException(); 
      } 
     } 
    } 

Mặc dù một khi bạn nhận thức được vấn đề, cảm thấy tự do để thực hiện giải pháp của riêng bạn;)
Chúc mừng hack.

5

Đó là vì bạn đã cung cấp cho lớp bên trong MyIterator thông số loại riêng của mình E. Lưu ý rằng E là thông số loại khác với thông số E của lớp kèm theo (bạn đã đặt tên cho chúng là E, nhưng chúng là hai tham số loại khác nhau).

Chỉ cần rời khỏi tham số kiểu cho các lớp bên trong:

private class MyIterator implements Iterator<E> { 
4

Tôi nghĩ rằng vấn đề là loại iterator lồng nhau của bạn được định nghĩa như là một lớp generic cũng tham số trên một loại không liên quan tên là E. Để khắc phục này, thay đổi

private class MyIterator<E> implements Iterator<E> 

Để

private class MyIterator implements Iterator<E> 

khai đầu tiên này nói rằng trình lặp cho loại của bạn có thể được tham số hóa trên bất kỳ loại nào, không chỉ là kiểu của vùng chứa bên ngoài. Nó cũng giới thiệu một biến kiểu mới gọi là E tách biệt với E trong khai báo bên ngoài. Định nghĩa thứ hai này nói rằng đối với bất kỳ loại vùng chứa nào, có một loại trình lặp không phải là loại chung chung đối với kiểu bên ngoài. Đây có lẽ là những gì bạn dự định.

Các vấn đề liên quan