김찬진의 개발 블로그
23/02/09 [내부클래스?] 본문
내부클래스의 종류는 변수의 선언위치에 따른 종류와 같다.
https://cjkimhello97.tistory.com/60
23/02/09 [인스턴스변수? 클래스변수? 지역변수?]
인스턴스변수, 클래스변수, 지역변수? 인스턴스변수 인스턴스가 생성될 때 생성된다. 인스턴스변수의 값으르 읽거나 저장하려면 생성자를 사용하여 인스턴스를 생성해야 한다. 인스턴스별로
cjkimhello97.tistory.com
내부클래스 | 특징 |
인스턴스클래스 | 외부 클래스의 멤버변수 선언위치에 선언하며 외부 클래스의 인스턴스멤버처럼 다뤄진다. 주로 외부 클래스의 인스턴스멤버들과 관련된 작업에 사용될 목적으로 선언된다. |
스태틱클래스 | 외부 클래스의 멤버변수 선언위치에 선언하며 외부 클래스의 클래스멤버(static멤버)처럼 다뤄진다. 주로 외부 클래스의 클래스멤버(static멤버), 특히 static 메서드에서 사용될 목적으로 선언된다. |
지역클래스 | 외부 클래스의 메서드나 초기화블럭 안에 선언하며 선언된 영역 내부에서만 사용될 수 있다. |
익명클래스 | 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용) |
내부인스턴스클래스에는 클래스멤버(클래스변수) 선언 불가
내부스태틱클래스에서 클래스멤버(클래스변수) 선언 가능
내부지역클래스에는 클래스멤버(클래스변수) 선언 불가
public class Test{
class InnerInstanceClass{ // 내부인스턴스클래스
int iv = 100;
// static int cv = 100; // 에러. 내부인스턴스클래스에는 클래스멤버(클래스변수) 선언불가
final static int CONST = 100; // final static은 상수이므로 내부인스턴스클래스에서 선언가능
}
static class InnerStaticClass{ // 내부스태틱클래스
int iv = 200;
static int cv = 200; // 내부스태틱클래스에서 클래스멤버(클래스변수) 선언가능
}
void myMethod(){
class InnerLocalClass{ // 내부지역클래스
int iv = 300;
// static int cv = 300; // 에러. 내부지역클래스에는 클래스멤버(클래스변수) 선언불가
final static int CONST = 300; // final static은 상수이므로 내부지역클래스에서 선언가능
}
}
public static void main(String[] args) {
System.out.println(InnerInstanceClass.CONST); // 100
System.out.println(InnerStaticClass.cv); // 200
}
}
내부지역클래스는 메서드 또는 초기화블럭 내에서 일회용임
public class Test{
class InnerInstanceClass{ // 내부인스턴스클래스
int iv = 100;
// static int cv = 100; // 에러. 내부인스턴스클래스에는 클래스멤버(클래스변수) 선언불가
final static int CONST = 100; // final static은 상수이므로 내부인스턴스클래스에서 선언가능
}
static class InnerStaticClass{ // 내부스태틱클래스
int iv = 200;
static int cv = 200; // 내부스태틱클래스에서 클래스멤버 선언가능
}
void myMethod(){
class InnerLocalClass{ // 내부지역클래스
int iv = 300;
// static int cv = 300; // 에러. 내부지역클래스에는 클래스멤버(클래스변수) 선언불가
final static int CONST = 300; // final static은 상수이므로 내부지역클래스에서 선언가능
}
}
void instanceMethod(){
InnerInstanceClass iic = new InnerInstanceClass();
InnerStaticClass isc = new InnerStaticClass();
// InnerLocalClass ilc = new InnerLocalClass(); // 에러. 내부지역클래스는 메서드 또는 초기화블럭 내에서 일회용임
}
static void staticMethod(){
// InnerInstanceClass iic = new InnerInstanceClass(); // 에러. 클래스멤버(static메서드)는 인스턴스멤버에 접근 불가
// 굳이 접근하려면 아래와 같이 인스턴스 생성해야 함
Test outerClass = new Test(); // 외부클래스 인스턴스를 먼저 생성한 이후에
InnerInstanceClass iic = outerClass.new InnerInstanceClass(); // 내부인스턴스클래스 인스턴스를 생성할 수 있다.
InnerStaticClass isc = new InnerStaticClass();
// InnerLocalClass ilc = new InnerLocalClass(); // 에러. 내부지역클래스는 메서드 또는 초기화블럭 내에서 일회용임
}
}
내부지역클래스에서 외부클래스의 인스턴스변수 접근가능
내부지역클래스에서 외부클래스의 스태틱변수 접근가능
내부지역클래스에서 외부클래스의 지역변수 접근가능(JDK1.8부터 가능)
내부지역클래스에서 외부클래스의 final지역변수 접근가능
public class Test{ // 외부클래스
private int outerIv = 0;
static int outerCv = 0;
class InnerInstanceClass{ // 내부인스턴스클래스
int iiv1 = outerIv; // 외부클래스의 private멤버 접근가능
int iiv2 = outerCv;
}
static class InnerStaticClass{ // 내부스태틱클래스
// int siv = outerIv; // 에러. 내부스태틱클래스에서 외부클래스의 인스턴스변수 접근불가능
static int scv = outerCv;
}
void myMethod(){
int lv = 0;
final int LV = 0; // JDK1.8부터 final 생략가능. 컴파일러가 자동으로 붙여줌
class InnerLocalClass{ // 내부지역클래스
int liv1 = outerIv; // 외부클래스의 인스턴스변수 접근가능
int liv2 = outerCv; // 외부클래스의 스태틱변수 접근가능
int liv3 = lv; // 외부클래스의 지역변수 접근가능(JDK1.8부터 가능)
int liv4 = LV; // 외부클래스의 지역변수 접근가능(final이므로)
}
}
}
내부인스턴스클래스의 인스턴스를 생성하기 위해선 외부클래스의 인스턴스부터 먼저 생성해야 한다.
내부스태틱클래스의 클래스변수(cv)는 인스턴스 생성할 필요없이 "외부클래스.내부스태틱클래스.멤버변수"로 접근가능
내부스태틱클래스의 인스턴스변수(iv)에 접근하기 위해서 내부스태틱클래스의 인스턴스를 생성해야 한다.
class OuterClass{ // 외부클래스
class InnerInstanceClass{ // 내부인스턴스클래스
int iv = 100;
}
static class InnerStaticClass{ // 내부스태틱클래스
int iv = 200;
static int cv = 300;
}
void myMethod(){
class InnerLocalClass{ // 내부지역클래스
int iv = 400;
}
}
}
public class Test{
public static void main(String[] args) {
// 내부인스턴스클래스의 인스턴스를 생성하기 위해선
OuterClass oc = new OuterClass(); // 먼저 외부클래스의 인스턴스를 생성한 후에
OuterClass.InnerInstanceClass ii = oc.new InnerInstanceClass(); // 내부인스턴스클래스 인스턴스를 생성해야 한다.
System.out.println("ii.iv: " + ii.iv); // 내부인스턴스클래스의 인스턴스(ii)의 멤버변수(iv)
System.out.println("OuterClass.InnerStaticClass.cv: " + OuterClass.InnerStaticClass.cv);
// 내부스태틱클래스의 클래스변수(cv)는 인스턴스 생성할 필요없이 "외부클래스.내부스태틱클래스.멤버변수"로 접근가능
OuterClass.InnerStaticClass si = new OuterClass.InnerStaticClass();
// 내부스태틱클래스의 인스턴스변수(iv)에 접근하기 위해서 내부스태틱클래스의 인스턴스를 생성해야 한다.
// 외부클래스.내부스태틱클래스 참조변수 = new 외부클래스.내부스태틱클래스생성자
System.out.println("si.iv: " + si.iv);
}
}
익명클래스는 클래스의 선언과 객체의 생성을 동시에 하는 방식이다.
내부인스턴스클래스를 익명클래스로 할 수도 있다. (클래스가 보이지 않을 뿐)
내부스태틱클래스를 익명클래스로 할 수도 있다. (클래스가 보이지 않을 뿐)
내부지역클래스를 익명클래스로 할 수도 있다. (클래스가 보이지 않을 뿐)
public class Test{
Object anonymous1 = new Object(){void method(){}}; // 내부인스턴스클래스를 익명클래스로
static Object anonymous2 = new Object(){void method(){}}; // 내부스태틱클래스를 익명클래스로
void myMethod(){
Object anonymous3 = new Object(){void method(){}}; // 내부지역클래스를 익명클래스로
}
}
참조변수 없이 익명클래스를 사용할 수 있다.
import java.awt.*;
import java.awt.event.*;
public class Test{
public static void main(String[] args) {
Button b = new Button("Start");
b.addActionListener(new ActionListener() { // 참조변수 없이 익명클래스 사용
public void actionPerformed(ActionEvent e){
System.out.println("ActionEvent occured!!!");
}
});
}
}
'1일1배움 > Java' 카테고리의 다른 글
문장(statement)과 표현(expression) (0) | 2023.03.07 |
---|---|
23/02/09 [인스턴스변수? 클래스변수? 지역변수?] (0) | 2023.02.09 |
23/02/02 [next(), nextLine()?] (1) | 2023.02.02 |
23/02/01 [replace()? replaceAll()? replaceFirst()?] (0) | 2023.02.01 |
23/02/01 [정규표현식(regex)?] (0) | 2023.02.01 |
Comments