javac가 "확인되지 않거나 안전하지 않은 작업 사용"경고를 발생시키는 원인


291

예를 들면 다음과 같습니다.

javac Foo.java
Note: Foo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

나는 동적으로 사용하는 클래스를 만들고 sun.misc.Unsafe출력에 이러한 힌트를 제공합니다
Davut Gürbüz

답변:


392

유형 지정자없이 컬렉션을 사용하는 경우 (예 : Arraylist()대신 ArrayList<String>()) Java 5 이상에서 발생합니다 . 컴파일러가 generics를 사용하여 형식이 안전한 방식으로 컬렉션을 사용하고 있는지 확인할 수 없음을 의미합니다 .

경고를 없애려면 컬렉션에 어떤 유형의 객체를 저장하고 있는지 구체적으로 지정하십시오. 그래서 대신

List myList = new ArrayList();

사용하다

List<String> myList = new ArrayList<String>();

Java 7에서는 Type Inference 를 사용하여 일반 인스턴스화를 줄일 수 있습니다 .

List<String> myList = new ArrayList<>();

Java 7에서는 이 컬렉션에 Type Interference 를 사용해도 동일한 경고가 표시됩니다 .ConcurrentHashMap<Integer, Object> objs = new ConcurrentHashMap()
Lucio

13
@Lucio 여전히 꺾쇠 괄호가 필요합니다. new ConcurrentHashMap<>()
Bill the Lizard

3
지적하면, 이것은 컬렉션에 한정되지 않습니다. Java 컴파일러가 일반적으로 유형 안전을 보장 할 수 없기 때문에 오류가 발생합니다. 예를 들어 다음 코드를 사용하여 동일한 경고가 생성됩니다. AbstractMap.SimpleEntry <String, String> entry = new AbstractMap.SimpleEntry ( "hello", "world");
semonte

1
-Xlint:uncheckedMAVEN
vanduc1102

200

"-Xlint : unchecked"스위치를 사용하여 제안한 작업을 수행하고 다시 컴파일하면보다 자세한 정보가 제공됩니다.

다른 답변에 설명 된대로 원시 유형을 사용하는 것 외에도 확인되지 않은 캐스트는 경고를 유발할 수 있습니다.

-Xlint로 컴파일하면 경고를 피하기 위해 코드를 다시 작성할 수 있습니다. 특히 변경할 수없는 레거시 코드와 통합하는 경우에는 항상 가능하지는 않습니다. 이 상황에서는 코드가 올바른지 알 수있는 위치에서 경고를 표시하지 않을 수 있습니다.

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}

12
더 많은 사람들이이 답변을지지하기를 바랍니다. @Bill the Lizard의 답변을 선택했습니다.하지만이 답변은 경고 자체에서 얼굴을 똑바로 쳐다보고 오류가 발생하는 또 다른 이유를 설명하고 있음을 보여준 내 마음에 가깝습니다.
toolbear

1
이것이 궁극적 인 답변입니다!
russellhoff 2009 년

이 답변은 해결책으로 표시되었습니다! 감사!
Alexander Malygin

19

Android Studio의 경우 다음을 추가해야합니다.

allprojects {

    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked"
        }
    }

    // ...
}

프로젝트의 build.gradle 파일에서이 오류가 발생한 위치를 확인하십시오.


고마워, 나는 이것을 추가함으로써 나의 경고가 어디에서 오는지 알았다
JackOuttaBox

나는이 경고를 받고 AS는 그것이 생성 된 클래스를 보여줍니다. 그리고 이것은 오류가 아니라 경고입니다. 왜이 옵션을 추가해야합니까? 귀하의 상황에 문제 클래스가 표시되지 않았습니까?
CoolMind

롤, 나는 단지 질문에 대답하고, 아니오 , 이것을 추가 할 때까지 문제는 보이지 않습니다.
Borzh

16

이 경고는 코드가 원시 유형으로 작동한다는 것을 의미합니다.

-Xlint:unchecked 

세부 사항을 얻기 위해

이처럼 :

javac YourFile.java -Xlint:unchecked

Main.java:7: warning: [unchecked] unchecked cast
        clone.mylist = (ArrayList<String>)this.mylist.clone();
                                                           ^
  required: ArrayList<String>
  found:    Object
1 warning

docs.oracle.com은 여기에 대해 이야기합니다 : http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html


1
나는 그렇게 생각합니다. 그는이 정확한 경고에 대한 오라클 문서로 연결됩니다.
Nick Westgate

6

나는 2 살짜리 수업과 새로운 수업이있었습니다. Android Studio에서 다음과 같이 해결했습니다.

allprojects {

    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked"
        }
    }

}

내 프로젝트 build.gradle 파일에서 ( Borzh 솔루션 )

그리고 일부 미신이 남는 경우 :

@SuppressWarnings("unchecked")
public void myMethod()
{
    //...
}

5

예를 들어 제네릭 컬렉션을 반환하는 함수를 호출하고 제네릭 매개 변수를 직접 지정하지 않은 경우.

기능을 위해

List<String> getNames()


List names = obj.getNames();

이 오류가 발생합니다.

그것을 해결하려면 매개 변수를 추가하면됩니다.

List<String> names = obj.getNames();

5

내가 올바르게 기억한다면, Java가 Generics를 추가했을 때 "확인되지 않거나 안전하지 않은 작업"경고가 추가되었습니다 . 일반적으로 유형에 대해 좀 더 명시 적으로 요구합니다.

예를 들어. ArrayList foo = new ArrayList();javac가 찾고 있기 때문에 코드 가 경고를 트리거합니다.ArrayList<String> foo = new ArrayList<String>();


2

나는 자주 볼 수있는 점검되지 않은 경고의 한 가지 예를 추가하고 싶습니다. Serializable과 같은 인터페이스를 구현하는 클래스를 사용하는 경우 실제 클래스가 아닌 인터페이스의 객체를 반환하는 메서드를 호출하는 경우가 종종 있습니다. 반환되는 클래스를 제네릭을 기반으로 형식으로 캐스팅해야하는 경우이 경고가 표시 될 수 있습니다.

다음은 간단한 (그리고 다소 어리석은) 예제입니다.

import java.io.Serializable;

public class SimpleGenericClass<T> implements Serializable {

    public Serializable getInstance() {
        return this;
    }

    // @SuppressWarnings("unchecked")
    public static void main() {

        SimpleGenericClass<String> original = new SimpleGenericClass<String>();

        //  java: unchecked cast
        //    required: SimpleGenericClass<java.lang.String>
        //    found:    java.io.Serializable
        SimpleGenericClass<String> returned =
                (SimpleGenericClass<String>) original.getInstance();
    }
}

getInstance ()는 Serializable을 구현하는 객체를 반환합니다. 실제 유형으로 캐스트해야하지만 이것은 확인되지 않은 캐스트입니다.


0

해결책은 <>과 같은 특정 유형을 사용하는 것 ArrayList<File>입니다.

예:

File curfolder = new File( "C:\\Users\\username\\Desktop");
File[] file = curfolder.listFiles();
ArrayList filename = Arrays.asList(file);

위의 코드 ArrayList는 특정 유형이 아니기 때문에 경고를 생성 합니다.

File curfolder = new File( "C:\\Users\\username\\Desktop");
File[] file = curfolder.listFiles();
ArrayList<File> filename = Arrays.asList(file);

위의 코드는 정상적으로 작동합니다. 다음의 세 번째 줄만 변경됩니다 ArrayList.


0

일반적인 형식으로 유지하고 다음과 같이 작성할 수 있습니다.

// list 2 is made generic and can store any type of Object
        ArrayList<Object> list2 = new ArrayList<Object>();

ArrayList의 유형을 Object로 설정하면 모든 유형의 데이터를 저장할 수있는 이점이 있습니다. -Xlint 또는 다른 것을 사용할 필요가 없습니다.


0

이 경고는

제네릭 형식 인 new HashMap () 또는 new ArrayList ()는 특정해야합니다. 그렇지 않으면 컴파일러가 경고를 생성합니다.

코드에 다음이 포함되어 있으면 그에 따라 변경해야합니다.

new HashMap () =>지도 맵 = new HashMap () new HashMap () =>지도 맵 = new HashMap <> ()

new ArrayList () => 목록 맵 = new ArrayList () new ArrayList () => 목록 맵 = new ArrayList <> ()


0

나는있다 ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;. value복잡한 구조 이기 때문에 ( JSON정리 하고 싶습니다 ) 숫자, 부울, 문자열, 배열에 대한 조합이 발생할 수 있습니다. 그래서 @Dan Dyer의 솔루션을 사용했습니다.

@SuppressWarnings("unchecked")
ArrayList<Map<String, Object>> items = (ArrayList<Map<String, Object>>) value;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.