Inner class의 이해와 특징
class내에 또 다른 class가 정의되는것을 의미
- Inner class가 필요한 이유는 지금까지 작업해 왔던 class들과는 다르게 독립적이지는 않지
만 하나의 member처럼 사용할 수 있는 특징이 있다.
Inner class를 정의 시 주의사항과 장점
Inner class는 외부 class의 모든 member들을 마치 자신의 member처럼 사용할 수 있다.
Static Inner class는 제외하고는 다른 Inner class는 항상 외부 class를 통해야 생성이 가능하다.
Inner class의 종류와 사용 방법
Member Inner class의 구성
Member Inner class Ex
Ex )
class InnerEx1
{
class InstanceInner
{
int iv = 100;
// static int cv = 100; // 에러! static변수를 선언할 수 없다.
final static int CONST = 100; // static final은 상수이므로 허용한다.
}
static class StaticInner
{
int iv = 200;
static int cv = 200; // static클래스만 static멤버를 정의할 수 있다.
}
void myMethod()
{
class LocalInner
{
int iv = 300;
// static int cv = 300; // 에러! static변수를 선언할 수 없다.
final static int CONST = 300;
}
}
public static void main(String[] args)
{
System.out.println(InstanceInner.CONST);
System.out.println(StaticInner.cv);
InnerEx1 ie = new InnerEx1(); // 객체생성
InstanceInner ii = ie.new InstanceInner(); // 객체생성
System.out.println(ii.iv);
}
}
결과 값
100
200
100
static을 선언한 변수는 바로 메모리에 생성되지만 static을 선언하지 않은 일반 int 변수는 바로 생성되지 않아서 객체를 생성해야 호출할 수 있다.
Ex )
class InnerEx2
{
private int outerIv = 0;
static int outerCv = 0;
class InstanceInner
{
int iiv1 = outerIv; // 외부 클래스의 private멤버도 접근 가능하다.
int iiv2 = outerCv;
}
static class StaticInner
{
//스태틱 클래스는 외부 클래스의 인스턴스멤버에 접근할 수 없다.
// int siv = outerIv;
static int scv = outerCv;
}
void myMethod()
{
int lv = 0;
final int Lv = 0;
class LocalInner
{
int liv1 = outerIv;
int liv2 = outerCv;
// 외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근 가능하다.
// int liv3 = lv;
int liv4 = Lv;
}
}
}
=> 결과 값은 출력문이 없어서 없으며 변수들이 각 클래스마다 호출이 가능한지 나타내어지고 있다.
Ex )
class Outer
{
class InstanceInner
{
int iv = 100;
}
static class StaticInner
{
int iv = 200;
static int cv = 300;
}
}
class InnerEx3
{
public static void main(String[] args)
{
Outer oc = new Outer();
Outer.InstanceInner ii = oc.new InstanceInner();
System.out.println("ii.iv : " + ii.iv);
System.out.println("Outer.StaticInner.cv : " + Outer.StaticInner.cv);
Outer.StaticInner si = new Outer.StaticInner();
System.out.println("si.iv : " + si.iv);
}
}
결과 값
ii.iv : 100
Outer.StaticInner.cv : 300
si.iv : 200
=> Outer 내부 클래스에 InstanceInner클래스 int iv는 Outer객체 생성과 InstanceInner객체 생성을 해야 한다. 즉 Outer.InstanceInner ii = oc.new InstanceInner(); 이런식으로 선언해야 호출할 수 있다. 반면에 static로 선언되어있는 staticInner클래스 static int cv는 객체 생성 없이 바로 호출해서(Outer.StaticInner.cv)사용할 수 있다.
------------------------------------------------------------------------------------------
Anonymous Inner class
Anonymous? 이름이 없는 것을 의미. Java의 program적으로 해석하면 정의된 class의 이름이 없다는 것이 된다.
Anonymous Inner class 조건
- 클래스의 이름이 없는 클래스
- 클래스의 선언과 객체생성을 동시에 한다.
- 오직 하나의 객체만 생성할 수 있는 1회용 클래스이다.
- 이름이 없기 때문에 생성자를 가질 수 없다.
- 조상클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용한다.
Anonymous Inner class 예
new 조상클래스()
{
// 내용...
}
new 인터페이스()
{
// 내용...
}
Ex )
interface TestInter
{
int data = 1000;
public void printData();
}
class AnonyInner
{
TestInter t = new TestInter()
{
public void printData()
{
System.out.println(data);
}
};
public static void main(String[] args)
{
AnonyInner ai = new AnonyInner();
ai.t.printData();
}
}
결과 값
1000
I/O
I/O : 입력(Input), 출력(Output)
간단한 예 : Scanner, System.out.println();
Input : 사용자가 프로그램에 데이터를 전달하는 것
Output : 프로그램이 결과를 내보내는 것
IN-Read-읽기전용빨대
Out-Write-쓰기전용빨대
|
읽기전용 |
쓰기전용 |
1byte 단위 처리 |
Java.io.InputStream |
Java.io.OutputStream |
2byte(char) 단위 처리 |
Java.io.Reader |
Java.io.Writer |
Reader, Writer -2byte인 char 단위로 데이터를 주고 받기 때문에 주로 문자열을 주고 받는 프로그래밍에 많이 쓰임
InputStream, OutPutStream – byte 기반의 데이터인 이미지나 데이터를 주고 받을 때 사용
InputStream, OutPutStream은 추상클래스로 선언되어있고, 많은 하위 클래스가 존재함
read() 메소드 – 하나의 바이트 데이터를 읽어낼 수 있음. 결과를 int 타입으로 반환함. Int 결과를 한 바이트의 데이터 값으로 생각해야함
음수가 나오는 경우 더는 읽어들일 만한 데이터가 없는 경우임
Read(byte[]) 메소드 - 한번에 byte[]만큼씩 데이터를 읽어냄
public class FileInputEx{
public static void main(String[] args) throws Exception
{
InputStream in = new FileInputStream("c"\\zzz\\aaa.txt");
while(true){
int data = in.read(); //한 byte씩 읽어드림
System.out.println(data);
if(data==-1){break;}
}
}
왜 While인가? 몇 번이나 루프를 돌아야 하는지 판단할 수 없기 때문에
write() 메소드
write(byte[]) – bytep[ 안에 있는 데이터를 한 번에 기록해줌.
flush() – 물을 내리다 라는 뜻, 밀어내기.
getBytes() 메소드 - 문자열은 byte[]로 변환할 수 있음
처리할 수 없는 다양한 상황 때문에 거의 모든 경우 입출력 프로그래밍은 IOException이라는 예외를 발생시키도록 되어있음. 사용한 다음에는 반드시 close() 를 이용해서 연결을 종료해야함. close는 반드시 finally에서 처리되어야함. Exception의 발생 여부와 관계 없이 종료되야함.
InputStream in = null;
OutputStream out = null;
try{
in = new FileInputStream(“C:\\zzz\\aaa.jpg”);
out = new FileOutputStream(“copy.jpg”);
while(true){
int data = in.read();
if(data==-1){break;}
}//end while
}catch(Exception e){
e.printStackTrace();
}finally{
if(in != null){
try{in.close();}catch(Exception e){
}
if(cout != null){
try{out.close();}catch(Exception e){
}
}//end finally
}//end main
}//end class
byte [] arr = new byte[5];
in count = in.read(arr);
-> 메모리 낭비가 일어난다.
write(byte[], int, int)
byte[]: 실제 데이터가 담겨 있는 byte[]
int : byte[] 내에서 데이터를 기록할 시작의 인덱스 번호
int: byte[] 내에서 몇 개의 데이터를 기록할 것인지 지정하는 숫자
out.write(arr, 0, data)
문자열을 byte[]로 변환해서 기록
public class ByteWriteWay{
public static void main(STring [] args) throws Exception{
String str = " 이 문자를 기록해볼까요?\n";
OutputStream out = new FileOutPutStream("aaa.txt");
byte [] arr = str.getByte();
out.write(arr);
out.close();
}
Reader에는 문자열로 읽어내는 기능이 없다. 그래서 BufferedReader 라는 클래스 사용.
BufferedReader의 메소드 중 readLIne()이라는 메소드를 통해서 문자열로 읽어내는 기능을 가지고 있음. String readLine() :: Reads a line of text.
'Programming > java 고급과정' 카테고리의 다른 글
<jsp:useBean> 액션태그 (0) | 2012.04.11 |
---|---|
java 고급과정 8일차 (0) | 2012.03.14 |
java 고급과정 6일차 (0) | 2012.03.12 |
java 고급과정 5일차 (0) | 2012.03.09 |
java 고급과정 4일차 (0) | 2012.03.08 |