>  기사  >  Java  >  Java의 가변 길이 매개변수 목록을 구문 분석하고 이를 사용할 때 주의할 점

Java의 가변 길이 매개변수 목록을 구문 분석하고 이를 사용할 때 주의할 점

高洛峰
高洛峰원래의
2017-01-19 15:13:041510검색

Java 변수 매개변수 목록

class A {}

모든 클래스는 Object에서 상속되므로 객체 배열을 매개변수로 사용할 수 있는 메서드:

public class parameter {
  static void printArray(Object[] args){
    for(Object obj : args){
      System.out.print(obj + " ");
    }
    System.out.println();
  }
   
  public static void main(String[] args){
    printArray(new Object[] {
        new Integer(47), new Float(3.14), new Double(11.11)
    });
    printArray(new Object[]{"one", "two", "there"});
    printArray(new Object[]{new A(), new A(), new A()});
  }
}

의 경우 Java SE5 이상 버전에서는 추가된 기능을 다음과 같이 작성할 수 있습니다.

public class parameter {
  public static void printArray(Object... args){
    for(Object obj : args){
      System.out.print(obj + " ");
    }
    System.out.println();
  }
   
  public static void main(String[] args){
    printArray(new Integer(47), new Float(3.14), new Double(11.11));
    printArray(47, 3.14F, 11.11);
    printArray("one", "two", "three");
    printArray(new A(), new A(), new A());
    printArray((Object[]) new Integer[]{1, 2, 3, 4});
    printArray();
  }
}

Object가 생각하는 매개변수 목록을 사용할 수 있습니다.

public class VarargType{
  static void f(Character... args){
    System.out.print(args.getClass());
    System.out.println(" length " + args.length);
  }
   
  static void g(int... args){
    System.out.print(args.getClass());
    System.out.println(" length " + args.length);
  }
   
  public static void main(String[] args){
    f('a');
    f();
    g(1);
    g();
    System.out.println(" int [] " + new int[0].getClass());
  }
}

Java 5에서 도입된 기능입니다. 메소드가 수신할 매개변수의 개수가 확실하지 않은 경우 이 기능이 유용할 수 있습니다.

예를 들어 IO 작업이 포함된 경우 입력과 출력이라는 두 개 이상의 스트림을 닫아야 합니다. 하나의 흐름.

public static void closeSilent(Closeable... closeables) {
   for (Closeable closeable : closeables) {
     if (closeable != null) {
        try {
          closeable.close();
        } catch (IOException ignored) {
        }
     }
   }
}

이 기능을 사용하기에 적합하다고 생각하는 곳은 다음과 같습니다.

이 매개변수는 동일한 유형을 갖습니다. 매개변수의 수는 정의되지 않으며 각각은 선택사항입니다.
이러한 매개변수의 목적은 동일합니다. 예를 들어 위의 내용은 모두 실행 종료입니다.
Java 가변 길이 매개변수 목록은 메소드 매개변수 목록 끝에만 배치할 수 있습니다.

Java 가변 길이 매개변수 목록 구현

Java 가변 길이 매개변수 목록 구현은 이러한 매개변수를 배열로 캡슐화하여 컴파일러에 의해 전달됩니다.

예를 들어 위 메소드의 시그니처는 실제로 closeSilent(Closeable[] closeables) void 입니다.

Step into the Pit

A, B 두 곳에서 호출되는 메소드가 있습니다. 9월에 A에 매개변수를 추가해야 했습니다. 그때 뇌가 이상해졌습니다. 그리고 가변 길이 매개변수 목록을 사용하기로 결정했는데, 매개변수 B를 변경하지 않으면 더 간단할 것 같아서 구덩이가 묻혔습니다.

최근 B는 여기에 두 개의 새로운 매개변수를 추가해야 합니다. 그런 다음 계속해서 메소드의 매개변수 목록에 매개변수 유형이 다르기 때문에 가변 길이 매개변수 목록은 Object 유형으로 선언됩니다. .

첫 번째 함정은 이 메서드에서 가변 길이 매개 변수의 요소를 가져올 때 일부 매개 변수가 전달되지 않은 것으로 간주하지 않고 배열 오프사이드 예외가 직접 발생한다는 것입니다. 즉시 가변 길이 매개변수 목록이 좋지 않다고 느껴서 필요하지 않고 일반 고정 형식 매개변수 전달로 변경했습니다.

수정 후 테스트 환경에서 테스트해보니 문제가 없었습니다. 프로덕션 환경에서 여러 클래스를 교체한 후 오류가 보고되고 메서드를 찾을 수 없습니다. 메서드 서명을 살펴보니 여전히 배열이고 교체되지 않았습니다. 소스 코드를 보면 호출 위치를 변경할 필요가 없으므로 테스트 환경이 완전히 패키지되어 있으므로 교체할 것으로 예상하지 못했습니다.

메소드의 시그니처는 컴파일 시 결정됩니다. 소스 코드 수준에서 변경할 필요가 없다고 해서 컴파일된 클래스를 교체할 필요가 없다는 의미는 아닙니다.

사실 이 불규칙 계약의 경우 소스 코드에서 상수 값을 변경한 후 해당 상수에 대한 모든 참조 없이 해당 상수를 정의하는 클래스 파일만 교체된다는 이야기를 전에 들었습니다. 파일이 다시 컴파일되고 교체되어 설명할 수 없는 문제가 발생합니다. 본질적으로 메소드 서명 상황과 동일한 문제입니다.

자바의 가변길이 매개변수 목록 분석 관련 글과 사용 시 주의사항은 PHP 중국어 홈페이지를 참고해주세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.