'Programming/Java'에 해당하는 글 56건

자바 소스 코드에서 @Override 처럼 @ 기호를 앞에 붙인 메타데이터 형태를 어노테이션(annotation) 이라고 하며 Java5 에서 추가되었다.

한글로 번역하면 comment 와 같은 '주석' 이 될 수 있지만 이 어노테이션은 단순한 주석이 아닌 메타 데이터의 일종으로 데이터의 데이터를 정의할 수 있다.

소스 코드에서 클래스, 메소드, 변수, 매개 변수, 패키지 등에 사용되어, 클래스가 컴파일되거나 실행될 때 어노테이션에 설정된 값에 따라 클래스의 방향이 결정된다.

컴파일러에 의해 생성된 클래스 파일의 어노테이션은 리플렉션(reflection) 을 통해 동작하게 된다.



자바 코드에 적용되는 내장 어노테이션


@Override - 메소드가 재정의(override) 된 것인지 확인한다. 부모 클래스나 구현된 인터페이스에 해당 메소드가 없으면 컴파일 오류가 발생한다.

@Deprecated - 앞으로 사용하지 않을 메소드임을 표시한다. 메소드가 사용되면 컴파일 경고가 발생한다.

@SuppressWarnings - 컴파일시 어노테이션 파라미터에 지정된 경고를 숨기도록 컴파일러에 지시한다.

@SafeVarargs - 제네릭스 가변인자(generics varargs) 파라미터를 사용한 메소드나 생성자의 모든 호출자에 대한 경고를 숨긴다. (Java7 이후)

@FunctionalInterface - 타입 선언이 함수형 인터페이스가 되도록 지정한다. (Java8 이후)



기타 어노테이션에 적용되는 어노테이션 (메타 어노테이션)


@Retention - 어노테이션의 저장 범주를 지정한다. (RUNTIME, CLASS, SOURCE)

@Documented - JavaDoc 에 현재 어노테이션을 표기하도록 지정한다.

@Target - 어노테이션이 적용될 Java 요소를 제한하기 위해 표시한다.

@Inherited - 어노테이션이 달린 클래스의 하위 클래스에 상속될 어노테이션을 표시한다. (기본적으로 어노테이션은 하위 클래스에 상속되지 않는다.)

@Repeatable - 어노테이션이 동일한 선언에 두 번 이상 적용될 수 있도록 지정한다. (Java8 이후)



아래는 @Override 어노테이션의 예제이다.


public class Animal {
    public void speak() {
    }
 
    public String getType() {
        return "Generic animal";
    }
}
 
public class Cat extends Animal {
    @Override
    public void speak() { // This is a good override.
        System.out.println("Meow.");
    }
 
    @Override
    public String gettype() { // Compile-time error due to mistyped name.
        return "Cat";
    }
}
cs


위 예에서 @Override 어노테이션은 해당 메소드가 상위 클래스에 있는 메소드인지 컴파일러가 검사하도록 지시한다.

이 경우, Cat 클래스의 gettype() 메소드가 사실상 Animal 클래스의 getType() 와 이름이 일치하지 않으므로 오류가 발생한다.

@Override 어노테이션이 없는 경우, Cat 클래스에 새로운 gettype() 메소드가 작성된다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,
Note: xxx.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
cs


정상적(?)으로 컴파일 되었고, 실행도 정상적이지만 나타나는 경고.

보통 map, list, collection, class 등 캐스팅시에 명시적인 정의가 안되어 있을 경우 나타나지만, 

어떤 타입이 올지 불명확한 상태에서의 캐스팅을 강제하는 것 역시 위 경고가 나타난다.


해당 코드를 확인하고 명확하게 수정해 주려면 아래 파라미터를 추가하고, 해당 파일을 지정하면 상세 로그가 나타난다.


> javac -Xlint:unchecked xxxxx.java
cs



예를 들어, 아래처럼 타입을 명시하였더라도,


HashMap<StringObject> map = new HashMap<>();
List<String> list = new ArrayList<>();
cs


다음 코드에서 경고가 났을 때,


list = (List<String>) map.get("itemList");
cs


아래처럼 바꿔주면 경고를 막을 수 있다.


if (map.get("itemList") instanceof List) {
    List insertQuery = (List) map.get("queryList");
}
cs


또는, 


검증되지 않은 연산자 관련 경고를 무시해주는 아래 어노테이션을 사용해도 된다.


@SuppressWarnings("unchecked")
cs


경고를 처리하지 않더라도 예외를 제외하고는 큰 문제가 없겠지만 그래도...

알아두면 좋다니~




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Object class

Programming/Java 2013. 2. 25. 22:23

toString

 

Object 클래스는 java.lang 패키지 소속이며, 컴파일시 자동 import 됩니다.
또한 모든 클래스는 이 Object 클래스를 자동으로 상속합니다.

 

명시하지 않아도 아래의 import 와 extends 를 사용한 것과 같습니다.

 

import java.lang.*
class DataObject extends Object {
}

 

여기에 더불어 Object 정보를 출력했을 때 default 로 표시되는 메소드는 toString() 입니다.
Object 정보는 클래스이름@고유번호(참조값) 으로 출력됩니다.

 

getClass().getName() + '@' + Integer.toHexString(hashCode())


보다시피 hashCode()는 객체의 고유번호를 10진수로 가져오고 toHexString 이 그 값을 16진수화 합니다.

 

class School
{
}

public class t1 
{
	public static void main( String[] args ) {
		School s = new School();
		System.out.println(s);
		System.out.println(s.toString());
	}
}
/*
School@785d65
School@785d65
*/

 

toString() 메소드는 결과를 알아보기 쉽게 재정의(Overriding)하여 사용하기도 합니다.

 

 

 

equals

 

new 생성자로 생성된 객체의 참조값을 비교할 때 Object 클래스의 equals()를 사용할 수 있습니다.
equals()는 == 연산자와 동일한 결과를 나타냅니다.
toString() 메소드처럼 주로 사용자가 재정의(Overriding)하여 사용합니다.
이것이 == 연산자와의 차이점입니다.

 

School s1 = new School();
School s2 = new School();

System.out.println( s1 );				// School@785d65
System.out.println( s2 );				// School@3bc257
System.out.println( s1 == s2 );			// false
System.out.println( s1.equals(s2) );	// false

 

하지만 이 외에도 미리 equals()를 재정의한 클래스도 있습니다.
String : 문자열 비교
Wrapper : 데이터 타입의 값 비교
Date : 날짜와 시간 비교
File : 경로 비교


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Object Stream

Programming/Java 2013. 2. 18. 01:01

바이트, 문자, 데이터 타입에 더하여 Object 역시 스트림 처리가 가능합니다.
저장 대상이 되는 클래스에 인터페이스(Serializable)만 붙여주면 ObjectInputStream / ObjectOutputStream 사용이 가능합니다.

 

import java.io.*;

class SampleData implements Serializable
{
	public String str;
	public int id;
	public SampleData(String str, int id) {
		this.str = str;
		this.id = id;
	}
	public String getSampleData() {
		return id + "=" + str;
	}
}

public class ObjectStreamMain {
	public static void main(String[] args) throws IOException, ClassNotFoundException {

		SampleData s1 = new SampleData("이씨",101);
		SampleData s2 = new SampleData("김씨",102);

		// Serialization
		FileOutputStream fos = new FileOutputStream("test.txt");  
		ObjectOutputStream oos = new ObjectOutputStream(fos);  
		oos.writeObject(s1);
		oos.writeObject(s2);
		oos.close();

		System.out.println(s1 + ":" + s1.getSampleData());		//SampleData@618d26:101=이씨
		System.out.println(s2 + ":" + s2.getSampleData());		//SampleData@88e2dd:102=김씨

		// Deserialization
		FileInputStream fis = new FileInputStream("test.txt");  
		ObjectInputStream ois = new ObjectInputStream(fis);  
		SampleData sd1 = (SampleData)ois.readObject();
		SampleData sd2 = (SampleData)ois.readObject();
		ois.close(); 

		System.out.println(sd1 + ":" + sd1.getSampleData());	//SampleData@203c31:101=이씨
		System.out.println(sd2 + ":" + sd2.getSampleData());	//SampleData@4fc156:102=김씨
	}
}

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Data Stream

Programming/Java 2013. 2. 18. 00:30

바이트나 문자 단위가 아닌 데이터 타입 단위로 처리하는 스트림입니다.
DataOutputStream / DataInputStream 으로 변환하며,
데이터 타입 별 write / read 메소드를 제공합니다.

 

import java.io.*;
public class DataStreamMain {
	public static void main(String[] args) throws IOException {
		// DataOutputStream을 이용하여 파일 바이트 단위에서 데이터 타입 단위 스트림으로 데이터 기록하기 
		FileOutputStream fos = new FileOutputStream("test.txt");  
		DataOutputStream dos = new DataOutputStream(fos);  
		dos.write(100);			// byte
		dos.writeInt(100);		// int
		dos.writeFloat(3.14f);	// float
		dos.writeChar('A');		// char
		dos.writeUTF("Oops4u");	// String
		dos.close();

		// DataInputStream을 이용하여 파일 바이트 단위에서 데이터 타입 단위 스트림으로 데이터 읽어오기 
		FileInputStream fis = new FileInputStream("test.txt");  
		DataInputStream dis = new DataInputStream(fis);  
		int b = dis.read();			// 1byte
		int i = dis.readInt();		// 4byte int
		float f = dis.readFloat();	// 4byte float  
		char c = dis.readChar();	// 2byte char
		String s = dis.readUTF();	// String
		dis.close(); 

		System.out.println( b + "," + i + "," + f + "," + c + "," + s); 
	}
}

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,