> Java > java지도 시간 > 본문

Java에서 내부 클래스 객체를 구성하고 객체에 액세스하는 방법을 설명합니다.

高洛峰
풀어 주다: 2017-01-20 17:42:38
원래의
1280명이 탐색했습니다.

리플렉션을 통해 내부 클래스 객체 생성
먼저 javalang 패키지 아래에 내부 클래스를 포함하는 클래스를 작성합니다.

package javalang;
 
public class Outer {
  public static class Inner1{}
}
로그인 후 복사

이 클래스는 공개 정적이므로 천천히 추가할 예정입니다. 나중에 이 수정자를 제거하세요.

Reflection을 통해 Inner1 객체를 생성하려면 먼저 Inner1의 Class 객체를 얻어야 합니다. Outer에 메인 메소드를 작성합니다:

public class Outer {
  public static class Inner1{}
   
  public static void main(String[] args) {
    System.out.println(Inner1.class);
  }
}
로그인 후 복사

출력 결과:

class javalang.Outer$Inner1
로그인 후 복사

그런 다음 클래스 이름이 올바른지 확인합니다:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1"));
}
로그인 후 복사

Run 잠시만요, 그렇죠. 그런 다음 이를 사용하여 개체를 만듭니다. 객체 생성은 생성자에 의존합니다. 이 클래스에 생성자 메서드가 있나요? 다음과 같이 쓸 수 있습니다:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors().length);
}
로그인 후 복사


실행하고 1을 출력합니다. 있는 것 같습니다. 그런 다음 이 구성 방법이 어떻게 보이는지 살펴보세요.

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors()[0]);
}
로그인 후 복사


출력 결과: public javalang.Outer$Inner1(). 이것이 기본 구축 방법입니다. 따라서 다음과 같이 작성할 수 있습니다.

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors()[0].newInstance();
}
로그인 후 복사

출력 결과: javalang.Outer$Inner1@ca0b6. 이는 실행이 성공했음을 나타냅니다.

다음으로 Inner의 public 키워드를 제거하고 다시 실행합니다. 결과는 오류였습니다:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
로그인 후 복사

이는 구성 방법을 찾을 수 없음을 의미합니다. 정말 그렇지 않나요? 기본 메소드를 다시 변경합니다:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors().length);
}
로그인 후 복사

출력 결과: 0. 정말 생성자가 없나요? 사실 아니죠. 단지 공법이 공개되지 않았을 뿐입니다. 이때 getDeclaredConstructors()를 사용하여 다음을 얻어야 합니다.

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors().length);
}
로그인 후 복사

출력 결과: 1. 시공방법을 찾아드립니다. 그런 다음 계속해서 이 생성자를 호출합니다.

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance());
}
로그인 후 복사

출력 결과: javalang.Outer$Inner1@ca0b6. 이제 리플렉션을 사용하여 비공개 내부 클래스의 개체를 생성할 수 있습니다.

다음으로 static 키워드를 삭제해 보겠습니다. 이때 오류가 보고되었습니다:
스레드 "main" java.lang.IllegalArgumentException: 잘못된 인수 개수

이것은 무엇을 의미합니까? 우리는 호출했을 때 매개 변수를 전달하지 않았으며 오류 내용은 매개 변수 수가 잘못되었다는 것입니다. 그러면 이 생성자에는 어떤 매개변수가 있습니까? 코드를 변경하여 살펴보겠습니다.

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0]);
}
로그인 후 복사

출력 결과: javalang.Outer$Inner1(javalang.Outer)

생성자에는 Outer 유형 매개변수가 필요한 것으로 나타났습니다. 이는 쉽습니다:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance(new Outer()));
}
로그인 후 복사

출력 결과:

javalang.Outer$Inner1@ca0b6
로그인 후 복사

그렇습니다. 비정적 내부 클래스에는 기본 생성 방법이 없고 생성 중에 외부 클래스의 인스턴스를 매개변수로 전달해야 하는 것 같습니다.


Java: 객체에 액세스하는 방법
Java 초보자의 고민은 객체를 메소드 변수로 정의할지 아니면 멤버 변수로 정의할지 결정하는 것입니다.

초보자는 처음에는 이런 것에 신경 쓰지 않습니다. 하지만 작성된 프로그램이 점점 더 커지고 클래스가 많아지면 이런 고민도 생깁니다.

하지만 여기서 쓰고 싶은 것은 객체를 원하는 대로 배열하여 언제든지 접근할 수 있도록 하는 방법입니다. 이것을 마스터하면 개체를 배치할 위치를 자유롭게 결정할 수 있습니다.

다음은 간단한 예입니다.

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    // 这里如何获得 main() 方法中的 date 变量?
  }
}
로그인 후 복사

anHourLater() 메서드에 설명된 대로 1시간 후의 날짜를 가져오려고 합니다. 무엇을 해야 할까요? 아래에는 여러 가지 방법이 있습니다.

(1) 매개변수 전달

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater(Date d) {
    Date anHourLater = new Date(d.getTime() + 3600000);
  }
}
로그인 후 복사

(2) 멤버로 정의됩니다. 멤버는 모든 메서드에서 액세스할 수 있으며 멤버 초기화는 멤버가 정의된 위치나 모든 메서드에 배치될 수 있습니다.

rree

(3) 다른 클래스에 넣어보세요. 다음 예제에서 DateHolder.date는 AccessingObject 클래스뿐만 아니라 동일한 패키지의 모든 클래스에서 액세스할 수 있습니다.

public class AccessingObject {
   
  private static Date date;
   
  public static void main(String[] args) {
    date = new Date();
    anHourLater();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    Date anHourLater = new Date(date.getTime() + 3600000);
  }
}
로그인 후 복사

이 세 가지 예를 비교해 보면 처음 두 개는 클래스 내부에서만 사용할 수 있고 비교적 안전합니다. 이 객체를 다른 클래스에서 직접 수정하지 않으려면 세 번째 방법을 사용하지 마세요.

첫 번째 방법과 두 번째 방법의 차이점은 객체를 메소드에서만 사용하면 해당 메소드가 실행될 때 객체를 쉽게 재활용할 수 있다는 점입니다. (참고, 즉시 재활용되지는 않습니다.) . 클래스의 멤버로 정의된 경우 객체는 해당 객체가 위치한 클래스가 재활용된 후에만 재활용됩니다. 분명히 첫 번째 방법이 자원을 가장 많이 절약하므로 첫 번째 방법을 사용하도록 노력해야 합니다.

이 세 가지 예를 살펴보면 main() 메서드가 anHourLater() 메서드에서 얻은 1시간 후의 시간을 얻으려는 경우에도 이에 상응하는 여러 가지 방법이 있습니다. 마지막 두 예제는 변경할 필요가 없습니다. 날짜 개체에 직접 액세스할 수 있습니다. 첫 번째 예제에는 두 가지 수정 방법이 있습니다.

(1) 반환 값

public class AccessingObject {
   
  public static void main(String[] args) {
    DateHolder.date = new Date();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    Date anHourLater = new Date(DateHolder.date.getTime() + 3600000);
  }
}
   
class DateHolder {
  public static Date date;
}
로그인 후 복사

(2) 매개변수의 내용을 직접 수정

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    Date anHourLater = anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static Date anHourLater(Date d) {
    return new Date(d.getTime() + 3600000);
  }
}
로그인 후 복사

뭔가 잘못되었습니다. 메소드 호출자가 좋아하는지 알 수 없습니다.

Java에서 내부 클래스 객체를 구성하고 객체에 액세스하는 방법을 설명하는 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿