HOWTO · Java

Java에서 예기치 않은 유형 오류 수정

이 자습서는 Java의 예기치 않은 유형 오류를 보여줍니다.

이 페이지의 내용

Java에서 대입 대상은 변수여야 합니다. charAt(i) 메서드는 문자 값을 반환하므로 DemoStr.charAt(i)와 같은 표현식은 대입문의 왼쪽에 올 수 없습니다. 반환된 문자를 변수에 대입하거나 변수에 추가하세요.

unexpected type 컴파일러 오류 이해하기

unexpected type 진단은 해당 위치에서 표현식이 어떤 역할을 할 수 있는지에 관한 것입니다. 아래 예에서 charAt(i)는 값을 반환할 뿐, 내용을 변경할 수 있는 변수를 가리키지 않습니다. 컴파일러의 required: variable 및 found: value라는 문구는 선언된 두 데이터 유형의 불일치가 아니라 대입 대상의 문제를 나타냅니다. 유형 불일치는 표현식의 유형이 다른 유형을 요구하는 위치에서 사용할 수 없을 때 발생하는 별개의 문제입니다. 여기서 단서는 +=의 왼쪽에 어떤 종류의 대상이 필요한지입니다. 형변환이나 선언된 유형을 바꾸어도 메서드 결과를 대입 가능한 대상으로 만들 수는 없습니다. 대입 연산자 바로 왼쪽의 표현식을 살펴보고, 변경할 수 있는 저장 공간을 가리키는지 확인하세요.

잘못된 대입으로 오류 재현하기

문자열 뒤집기 예에서 실패하는 연산은 DemoStr.charAt(i) += ReversedString;입니다. 이 연산은 charAt이 반환한 문자를 바꾸려 하지만, 반환값은 값일 뿐입니다. 이 대입에 대한 컴파일러 진단은 왼쪽에 변수가 필요하지만 값이 왔다고 표시합니다. 컴파일러 진단의 형식은 다를 수 있으므로, 이 설명은 실제 컴파일러 출력을 옮긴 것이 아닙니다. +=에도 일반 = 대입과 마찬가지로 쓰기 가능한 대상이 필요합니다. 메서드 호출로 문자를 읽거나 비교하거나 다른 연산에 전달할 수는 있지만, 반환된 문자는 원래 문자열 안에서 이름으로 지정된 저장 위치가 아닙니다. Java 문자열은 변경할 수 없으므로, 여기서는 DemoStr 안의 문자를 수정하는 대신 별도의 결과를 만들어야 합니다.

변수에 대입하도록 수정하기

결과 변수를 왼쪽에 두고 charAt(i)가 반환하는 각 문자를 그 변수에 추가하세요. 다음 완전한 예제는 원본 문자열의 마지막 인덱스부터 첫 번째 인덱스까지 순회합니다. length() - 1에서 시작하면 마지막 문자를 선택하고, i를 감소시키면 0까지 앞쪽 인덱스를 차례로 방문합니다. 이 순서로 원본은 그대로 둔 채 결과를 거꾸로 만듭니다. 입력 문자열이 비어 있으면 시작 인덱스가 -1이므로 반복문 본문은 실행되지 않고 프로그램은 빈 줄을 출력합니다.

다음 예제를 실행해 보세요.

public class AssignmentFix {
    public static void main(String[] args) {
        String DemoStr = "delftstack";
        String ReversedString = "";

        for (int i = DemoStr.length() - 1; i >= 0; i--) {
            ReversedString += DemoStr.charAt(i);
        }

        System.out.println(ReversedString);
    }
}

출력:

kcatstfled

핵심 수정 사항은 ReversedString에 대입하고, charAt(i)가 추가할 문자를 제공한다는 점입니다. 긴 문자열에서 문자열을 반복해서 연결하면 중간 문자열이 많이 만들어질 수 있습니다. 이 반복문은 대입 대상의 수정 방법을 명확히 보여 주며, 많은 문자를 누적할 때는 보통 StringBuilder를 사용하는 편이 적합합니다.

StringBuilder로 문자열 뒤집기

간단히 문자열을 뒤집으려면 원본으로 StringBuilder를 만들고 reverse()를 호출한 다음 결과를 다시 String으로 변환하면 됩니다. 이는 문자열을 뒤집는 또 다른 방법이며, 대입 대상 오류를 수정하는 데 꼭 필요한 방법은 아닙니다.

public class BuilderReverse {
    public static void main(String[] args) {
        String DemoStr = "delftstack";
        String ReversedString = new StringBuilder(DemoStr).reverse().toString();
        System.out.println(ReversedString);
    }
}

출력:

kcatstfled

두 예제 모두에서 charAt(i)가 반환하는 값은 읽거나 추가할 수 있지만, 대입 대상은 변수여야 합니다. StringBuilder.reverse()는 빌더의 내용을 뒤집고, toString()은 결과를 일반 String으로 반환합니다. 문자가 누적되는 과정을 확인하거나 사용자 지정 처리를 추가하려면 반복문을 선택하고, 문자열을 뒤집기만 하면 된다면 빌더 방식을 선택하세요. 어느 방법도 메서드 결과에 대입하지 않습니다.