2013-05-23 2 views
0

Я использую Comparator для сравнения файлов по размеру, но когда я попытался скомпилировать свой код, я получил предупреждение: «java использует неконтролируемые или небезопасные операции». Я поместил свой код в комментарии и работал над программой, поэтому я думаю, что это проблема с сортировкой в ​​классе Comparator. Вот мой код:Предупреждение Java Comparator

public class size implements Comparator { 

    @Override 
    public int compare(Object o1, Object o2) { 

     long s1 = ((Class)o1).getSize(); 
     long s2 = ((Class)o2).getSize(); 

     if (s1 > s2){ 
      return 1; 
     } 
     else if (s1 < s2){ 
      return -1; 
     } 
     else { 
      return 0; 
     } 
    } 
} 
+0

В какой строке есть предупреждение? – thegrinner

+0

Возможный дубликат http://stackoverflow.com/questions/197986/what-causes-javac-to-issue-the-uses-unchecked-or-unsafe-operations-warning – Joetjah

+0

Что такое 'Class'? В 'java.lang.Class' нет' getSize() '. – johnchen902

ответ

3

Эти две строки содержат опасные броски:

long s1 = ((Class)o1).getSize(); 
long s2 = ((Class)o2).getSize(); 

В связи с небезопасным бросок это выражение: (Class)o1, вы бросаете o1, который является объектом класса, без предварительной проверки, что o1 является экземпляром Class

Ваша программа работает хорошо, если вы предоставляете экземпляры класса методу. Проблема в том, что вы не можете удостовериться, что никто не вызывает метод yur с объектом, который не является классом.

Вам следует реализовать безопасный компаратор типа, если ваша версия java более новая, чем 1.4.

public class size implements Comparator<Class> { 
    @Override 
    public int compare(Class o1, Class o2) { 
     // compare the two class objects 
+0

Но если я удаляю эти приведения, метод геттера не может быть разрешен. – Erik

+0

См. Мой отредактированный ответ – nakosspy

+0

@Erik, btw это java.lang.Class объекты те, которые вы пытаетесь сравнить? Поскольку метод getSize() отсутствует в java.lang.Class. – nakosspy

-1
long s1 = ((Class)o1).getSize(); 

где он жалуется. Я думаю, что это фиксирует это:

if(o1 instanceof Class) 
{ 
    long s1 = ((Class)o1).getSize(); 
} 

По сути вы не гарантировано, что o1 является Class

2

объявить Comparator как Comparator<File> и заменить метод сравнения с

compare(File o1, File o2) 

EDIT: Или Comparator<Class> если вы сравниваете классы. Это то, что вы, кажется, делают

0

Вы должны использовать o1.getClass() вместо литья

2

Я думаю, что есть ошибки в коде. Вы должны сделать что-то вроде этого:

public static void main(String[] args) { 
    File parentFile = new File("path to your parent file"); 
    File[] files = parentFile.listFiles(); 
    Arrays.sort(files, new Comparator<File>() { 
    @Override 
    public int compare(File o1, File o2) { 
     return new Long(o1.length()).compareTo(o2.length()); 
    } 
}); 
0

Во-первых, вы используете компаратор в качестве сырьевого типа. Это неверно, добавьте к нему аргумент типа, а затем выполните команду compare(File, File).

Во-вторых, производительность вашего компаратора будет ужасной, потому что length приводит к собственному системному вызову, чтобы узнать размер файла.

Для решения проблемы производительности вам необходимо написать класс-оболочку для файлов. Он может непосредственно реализовать Comparable:

public class FileBySize implements Comparable<FileBySize> { 
    private final File f; 
    private final Long size; 
    public FileBySize(File f) { this.f = f; this.size = f.length(); } 
    @Override public int compareTo(FileBySize other) { 
    return this.size.compareTo(other.size); 
    } 
} 
0

Это право. Comparator - это параметризованный интерфейс, то есть класс, который определяется с помощью дженериков.

Это путь, вы должны реализовать компаратор, чтобы избежать как предупреждения и вероятность того, что ClassCasetException брошено:

public class SizeComparator implements Comparator<Object> { 
...... 
} 

Ваш компаратор вид чего-то особенного. Он работает с любым объектом.Это причина, по которой я написал Comparator<Object>. В большинстве случаев вы бы определить параметр класса более конкретно и использовать один и тот же класс в compare() способом, например

public class SizeComparator implements Comparator<String> { 
    public int compare(String s1, String s2) { 
     ....... 
    } 
} 

BTW в вашем случае вы можете также определить свой компаратор следующим образом:

public class SizeComparator implements Comparator<T extends Object> { 
    public int compare(T o1, T o2) { 
     ....... 
    } 
} 

И обратите внимание на то, что я изменил имя вашего класса. Важно соблюдать широкие правила именования.

Смежные вопросы