문제

이것에서 의문, tofubeer는 일반화 된 것을 만드는 데 문제가있었습니다 IterableEnumeration.

답은 Jcrossley3 이이 링크를 가리키는 것에서 나왔습니다 http://www.javaspecialists.eu/archive/issue107.html 문제를 거의 해결했습니다.

내가 얻지 못하는 것이 여전히 있습니다. Erickson이 효과적으로 지적했듯이 실제 문제는 다음과 같습니다.

매개 변수화 된 유형을 구성 할 때 와일드 카드를 지정할 수 없습니다.

그러나 선언에서 와일드 카드를 제거하는 것은 작동하지 않았습니다.

final IterableEnumeration<ZipEntry> iteratable 
                  = new IterableEnumeration<ZipEntry>(zipFile.entries());

다음 오류가 발생합니다.

Main.java:19: cannot find symbol
symbol  : constructor IterableEnumeration(java.util.Enumeration<capture#469 of ? extends java.util.zip.ZipEntry>)
location: class IterableEnumeration<java.util.zip.ZipEntry>
        final IterableEnumeration<ZipEntry> iteratable = new IterableEnumeration<ZipEntry>(  zipFile.entries());
                                                         ^
1 error

그러나 Javaspecialist의 샘플은 다음과 같습니다.

  IterableEnumeration<String> ie =
              new IterableEnumeration<String>(sv.elements());

내가 발견 할 수있는 유일한 차이점은 Javaspecialists 블로그에서 Enumeration a에서 온다 Vector 서명은 다음과 같습니다.

public Enumeration<E> elements()

실패한 것은 나옵니다 ZipFile 서명은 다음과 같습니다.

public Enumeration<? extends ZipEntry> entries()

마지막으로,이 모든 것은 링크에서 제안 된 For-each Construct와 정적 메소드에 의해 흡수됩니다.

for(final ZipEntry entry : IterableEnumeration.make( zipFile.entries() ))  {
    if(!(entry.isDirectory())) {
        names.add(entry.getName());
    }
}

하지만!! 그 뉴스 레터의 요점은이 문제를 해결하는 것이 아니라 구문이 추악 해 보이기 때문에 일반 유형을 지정할 필요가 없습니다!

그래서 .. 내 질문은 다음과 같습니다.

무슨 일이 일어나고 있습니까?

인스턴스를 만드는 이유는 무엇입니까? IterableEnumeration 매개 변수가 an 일 때 작동합니다 Enumeration 누구의 유형입니다 <? extends SomeClass> ? 그리고 왜 마찬가지로 건설이 문제를 삼키는가? !!!

왜이 효과가 있습니까?

for(final ZipEntry entry : IterableEnumeration.make( zipFile.entries() ))  {

그러나 이것은 작동하지 않습니까?

final IterableEnumeration<ZipEntry> iteratable
                     = IterableEnumeration.make( zipFile.entries() );

아래는 tofubeer의 원래 코드의 (약간) 수정 된 버전입니다.

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.Vector;

public class Main {
    private ZipFile zipFile;

    public Set<String> entries() {

        final Vector<ZipEntry>    vector = new Vector<ZipEntry>();
        // why this works.
        //final IterableEnumeration<ZipEntry> iteratable = new IterableEnumeration<ZipEntry>( vector.elements() );

        // but this do not.
        //final IterableEnumeration<ZipEntry> iteratable = new IterableEnumeration<ZipEntry>( zipFile.entries() );

        // nor this 
        final IterableEnumeration<ZipEntry> iteratable = IterableEnumeration.make( zipFile.entries() );

        // And what's with the for-each that doesn't care about the type?    
        final Set<String>   names = new HashSet<String>();

        for(final ZipEntry entry : IterableEnumeration.make( zipFile.entries() ))  {
            if(!(entry.isDirectory())) {
                names.add(entry.getName());
            }
        }

        return (names);
    }
}

class IterableEnumeration<T> implements Iterable<T> {
    private final Enumeration<T> enumeration;

    public IterableEnumeration(final Enumeration<T> e) {
        enumeration = e;
    }

    public Iterator<T> iterator() {
        return new Iterator<T>() { 
             public boolean hasNext() {
                return (enumeration.hasMoreElements());
            }

            public T next() {
                return (enumeration.nextElement());
            }

            public void remove() {
                throw new UnsupportedOperationException("Cannot remove via an Enumeration");
            }
        };
    }
    // As suggested by http://www.javaspecialists.eu/archive/Issue107.html
    // but doesn't help with: final IterableEnumeration<ZipEntry> iteratable = IterableEnumeration.make( zipFile.entries() );
    public static <T> Iterable<T> make(Enumeration<T> en) {
        return new IterableEnumeration<T>(en);
    }
}

나는 그것을 이해하고 싶다 !!

도움이 되었습니까?

해결책

Foreach 루프에서 무슨 일이 일어나고 있는지 잘 모르겠지만 Zipfile.entries ()에서 반환되지 않은 지정되지 않은 유형을 수락하려면 반복 가능한 선언에 와일드 카드를 추가해야합니다.

바꾸다

    private final Enumeration<T> enumeration;

    public IterableEnumeration(final Enumeration<T> e) {
        enumeration = e;
    }

    public static <T> Iterable<T> make(Enumeration<T> en) {
        return new IterableEnumeration<T>(en);
    }

와 함께

    private final Enumeration<? extends T> enumeration;

    public IterableEnumeration(final Enumeration<? extends T> e) {
        enumeration = e;
    }

    public static <T> Iterable<T> make(Enumeration<? extends T> en) {
        return new IterableEnumeration<T>(en);
    }

다른 팁

여기서 근본적인 문제는 언제입니다 압축 파일 제네릭을 지원하기 위해 변경되었으며 관리자는 반환 유형을 entries() 행동 양식 Enumeration<? extends ZipEntry> (아마도 서브 클래스의 방법이 될 것입니다 JarFile 돌아올 수 있습니다 Enumeration<JarEntry>). 이것은 당신이보고있는 문제를 일으킨다.

왜냐하면 Enumeration<T> 공분산으로 사용됩니다 (항상 - 값만 리턴하는 것만으로도), 항상 방법 인수를 가져 가야합니다. Enumeration<? extends T>.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top