// 1. 바깥 클래스 객체화클래스명 객체명 = new 생성자();// 2. 안쪽 클래스 객체화 - 바깥클래스 객체가 필수[바깥클래스명.]안쪽클래스명 객체명 = 바깥클래스의객체명.new 안쪽클래스의생성자();// 1Outer out = new Outer(); // 2Outer.Inner in = out.new Inner();
public class Outer { int i; public Outer() { System.out.println("바깥 클래스의 생성자"); } public void outMethod() { System.out.println("바깥 클래스의 method, i="+i); // 안쪽클래스를 객체화 Outer.Inner in = this.new Inner(); in.inMethod(); } ////////////////////// 안쪽 클래스 시작 //////////////////////// public class Inner { int j; public Inner() { System.out.println("안쪽 클래스의 생성자"); } public void inMethod() { // 안쪽클래스에선 바깥클래스의 변수, method를 사용가능 System.out.println("안쪽 클래스의 method, j=" +j+", 바깥 클래스의 자원 i="+i); } } ////////////////////// 안쪽 클래스 끝 ////////////////////////// public static void main(String[] args) { // 1. 바깥 클래스의 객체화 Outer out = new Outer(); out.i = 10; out.outMethod(); // 안쪽클래스의 자원을 직접 접근사용불가 // out.j = 20; // out.inMethod(); // 2. 안쪽 클래스의 객체화(바깥 클래스 객체사용) // 바깥클래스명.안쪽클래스명 객체명 = 바깥클래스의객체명.new 안쪽생성자(); // 바깥클래스명은 생략할 수 있다 // Outer.Inner in = out.new Inner(); Inner in = out.new Inner(); in.j = 12; in.inMethod(); }}
nested class (중첩 클래스)
안쪽 클래스를 static 변수처럼 사용할 때 사용
이벤트를 공용 이벤트로 처리할 때
내부 클래스의 자원을 가급적이면 static으로 만들어 사용.
static class라고 내부도 모두 static인게 아님.
자원 중 static인 것만 객체화 없이 사용 가능
static 안쓰면 객체화 필요
클래스명.변수명 또는 클래스명.메소드명() 형태로 사용
/*** 내부클래스를 static 변수처럼 사용할 수 있는 중첩클래스(nested class)*/public class NestedOuter { int i; static int j; public NestedOuter() { System.out.println("바깥클래스 생성자"); } public void outInstanceMethod() { System.out.println("바깥클래스의 instance method"); } public static void outStaticMethod() { System.out.println("바깥클래스의 static method"); } /////////////////////// Nested class 시작 /////////////////// public static class NestedInner { // int instance_i; // instance 변수, instance 생성 권장안함 static int instance_j; // static 변수 /*public NestedInner() { // static 클래스이므로 인스턴스화 X System.out.println("중첩클래스 생성자"); }*/ public void inMethod() { // 객체화없이 사용불가 System.out.println("안쪽 클래스의 instance method"); } public static void inStaticMethod() { System.out.println("안쪽 클래스의 static method"); // i는 인스턴스 변수라 직접 사용불가(객체화 필요) System.out.println("바깥클래스의 자원 사용 " + "i=사용불가, j="+NestedOuter.j); // outInstanceMethod(); // 인스턴스 메소드라 사용불가 NestedOuter.outStaticMethod(); } } /////////////////////// Nested class 끝 ///////////////////// public static void main(String[] args) { // static 영역을 사용할 때에는 객체화없이 클래스명.변수명, // 클래스명.method명으로 사용(static 방식) // NestedInner.inMethod(); // 객체화 안해서 사용불가 NestedInner.inStaticMethod(); // static 이므로 중첩클래스는 객체화 권장안함 // NestedInner ni = new NestedInner(); // System.out.println(ni.instance_i); }}
컴파일 하면 .class파일(byte code) 생성
바깥클래스명.class
Outer.class
바깥클래스명$안쪽클래스명.class
자바에서 '.'은 그 안을 의미, 혼동가능-> $사용
$붙으면 이너클래스
$는 자바언어 외부에서 자바언어 내부를 의미하는 기호
파일명으로 nested인지 inner인지는 구분하기 힘듦.
local class
안쪽 클래스를 지역변수처럼 사용할 때 사용
method안에 정의하는 클래스
method가 호출되었다고 객체가 생성되지 않는다.
객체 중 생명이 가장 짧다.
안쪽클래스에서 인스턴스 변수는 참조가능하나 지역변수, parameter는 final이 붙은 변수만 참조가능.
/*** method안에 클래스를 정의하는 지역class 사용.* 생성된 객체를 지역변수처럼 사용하는 클래스*/public class LocalOuter { int i; public LocalOuter() { System.out.println("바깥 클래스의 생성자"); } public void method(int param_i, final int param_j) { // parameter는 지역변수 int local_i = 0; final int local_j = 0; /////////////////////// 지역 클래스 시작 ////////////////////////// class Local { int loc_i; public Local() { System.out.println("지역 클래스의 생성자"); } public void locMethod() { System.out.println("지역 클래스의 method"); System.out.println("외부 클래스의 instance 변수 i="+i); // jdk 1.8이전은 final이 붙은 지역변수만 사용가능 System.out.println("매개변수(parameter) param_i=" +param_i+", param_j="+param_j); System.out.println("지역변수 local_i=" +local_i+", local_j="+local_j); // jdk1.8부터는 final이 붙지 않은 지역변수의 출력은 가능하지만 // final이 붙지 않아도 값할당은 되지 않는다(final처럼 사용됨) // local_i = 2018; // pram_i = 2018; } } /////////////////////// 지역 클래스 끝 //////////////////////////// // 지역클래스를 사용하려면 메소드에서 지역클래스 객체화 필요 // 지역클래스의 객체화 Local lo = new Local(); // 생성된 객체로 클래스내 자원을 사용할 수 있다. // loc_i=100; // 직접 사용불가 lo.loc_i=100; lo.locMethod(); System.out.println(lo.loc_i); System.out.println("method 호출"); } public static void main(String[] args) { LocalOuter lo = new LocalOuter(); lo.method(4, 12); }}
anonymous inner class
익명 클래스(이름 없는 클래스)
매개변수에 입력되는 값(argument, 인수 값)으로 클래스를 사용
한번 호출로 작업이 종료되는 경우 사용
Compile되면 바이트코드로 바깥클래스는 바깥클래스명.class처럼 변환되고 익명클래스는 바깥클래스명$1.class처럼 숫자로 끝난다.
// interface를 매개변수로 받으면 절차가 많음public interface AnonyInter { public String getName(); public String getMsg();}// AnonyInter 구현하는 클래스 AnonyImple 생성public class AnonyImpl implements AnonyInter{ @Override public String getName() { return "쵸몬도"; } @Override public String getMsg() { return "온뇨쇼"; }}// useAnonyInter의 인수로 인터페이스 구현한 클래스 객체 전달public class TestAnony{ public void useAnonyInter(AnonyInter ai) { System.out.println(ai.getMsg()+" "+ai.getName()); } public static void main(String[] args) { // interface는 객체화가 되지 않는다. // AnonyInter ai = new AnonyInter(); // interface가 매개변수 였을 때 // 1. 인터페이스를 구현한 클래스를 생성 // 2. 구현클래스로 객체를 생성 AnonyInter ai = new AnonyImpl(); // is-a // 3. 매개변수를 가진 메소드를 호출하기위해 객체생성 TestAnony ta = new TestAnony(); // 4. method 호출 ta.useAnonyInter(ai); }}
// anonymouse innerclass 문법호출하는method명(new 구현인터페이스명|부모클래스명() { // '{' 앞의 대상을 부모로 하는 이름 없는 클래스가 생성됨 @Override method재정의() { ... } ... method정의() { ... }});
public class TestAnony{ public void useAnonyInter(AnonyInter ai) { System.out.println(ai.getMsg()+" "+ai.getName()); } public static void main(String[] args) { TestAnony ta = new TestAnony(); // anonymous inner class를 사용하면 class를 따로 만들 필요가 없다. ta.useAnonyInter(new AnonyInter() { @Override public String getName() { return "쵸묜도"; } @Override public String getMsg() { return "온뇨쇼"; } }); }}
import
외부 package내의 다른 클래스나 interface를 참조하여 사용하기 위한 것.
java.lang package는 자동 import 된다.
package 선언과 class 선언 사이에서 import 수행
import를 하면 다른 패키지 클래스들을 같은 패키지에 있는 것처럼 패키지명 없이 사용가능해진다.
jdk 1.5부터는 static import 기능이 추가됨.
주의
패키지명은 다르나 클래스나 interface명이 같은 경우 하나만 import 받을 수 있다.
나머지 하나는 **full path(패키지명 모두 기술하는 것)**로 처리
package 패키지명;import 패키지명.*; // 특정 패키지내의 모든 클래스를 참조하는 것import 패키지명.클래스명; // 특정 패키지내 하나의 클래스를 참조하는 방법(권장)...public class 클래스명 {...
import java.util.List;// 패키지는 다르나 이름이 같은 클래스는 둘 중 하나만 import 받을 수 있다. // import java.awt.List;// 같은 이름의 클래스(interface)는 둘 중 많이 사용되는 것을 import로 처리하고,// 적게 사용되는 것을 full path로 처리한다.List list = null; // java.util.Listjava.awt.List list1 = null; // java.awt.List
static import
다른 클래스의 static 변수(상수) 또는 static method를 내 클레스에 존재하는 것처럼 사용할 때 사용
jdk 1.5부터 지원
import static 패키지명.클래스명.static변수; // 변수나 상수 사용할 때import static 패키지명.클래스명.static메소드; // method 사용할 때
import static java.lang.Integer.MAX_VALUE;//같은 이름의 상수는 하나만 import//import static java.lang.Byte.MAX_VALUE;import static java.lang.Integer.parseInt;import static java.lang.System.out;public class StaticImport { public static void main(String[] args) { // 클래스명 없이 메소드 호출 int i = parseInt("20181204"); out.println(i); out.println(MAX_VALUE); }}