Java에서는 다음과 같이 인스턴스(객체)를 만드는 방법이 있다.

 

   new
 


일반적으로 인스턴스는 Java의 예약어 new를 사용해서 만든다. 다음과 같이 하면 Something 클래스의 인스턴스를 만들고 변수 obj에 대입할 수 있다.

--> obj라는 이름을 가지는 Something 클래스 타입의 객체를 가진다 라고 말할 수 있겠다.

Something obj = new Something();

 이 경우 클래스 이름(여기에서는 Something)을 소스 안에 기술할 필요가 있다.

 

   clone()
 

Prototype 패턴에서 등장했던 clone 메소드를 사용하면 이미 존재하는 인스턴스를 기초로 새로운 인스턴스를 만들 수 있다. 다음과 같이 하면 자신(this)을 기초로 새로운 인스턴스(객체)를 만들 수 있다(단, 생성자는 호출되지 않는다).

java.lang
클래스 Class<T>

java.lang.Object 
java.lang.Class<T>

java.lang
클래스 Object

java.lang.Object

clone

protected Object  clone()


throws
CloneNotSupportedException

이 객체의 카피를 작성해, 돌려줍니다. 「카피」의 정확한 이유는, 객체의 클래스에 의해 다릅니다. 일반적으로는, 임의의 객체 x 에 대해, 다음의 식
 x.clone() ! = x
하지만 true 이며, 다음의 식
 x.clone(). getClass() == x.getClass()
도 true 인 것입니다만, 이것들도 절대적인 요건이 아닙니다. 또 다음의 식
 x.clone(). equals(x)
도 일반적으로 true 가 됩니다만, 이것도 절대적인 요건이 아닙니다.

일반적으로,super.clone 를 호출하는 것으로 반환되는 객체를 취득할 수 있습니다. 클래스 및 그 슈퍼 클래스 모든 것 (Object 를 제외한다)이 이 규칙에 따르는 경우,x.clone(). getClass() == x.getClass() 가 성립합니다.

일반적으로, 이 메소드에 의해 반환되는 객체는, 이 객체 (복제되고 있다)로부터 독립하고 있을 필요가 있습니다. 이 독립성을 달성하기 위해(때문에),super.clone 가 돌려주는 객체의 필드를 1 개 이상 (객체가 돌려주기 전에) 변경하는 것이 필요하게 되는 경우가 있습니다. 이것은, 일반적으로, 복제하는 객체의 내부 「심층 구조」를 구성하는 가변 객체의 카피, 및 이러한 객체에의 참조를 카피에의 참조에 옮겨놓는 것을 의미합니다. 클래스에 프리미티브(primitive) 필드 또는 불변 객체에의 참조만이 포함되는 경우, 일반적으로,super.clone 에 의해 반환되는 객체내의 필드를 변경할 필요는 없습니다.

Object 클래스의 clone 메소드는, 특정의 복제 처리를 실행합니다. 우선, 이 객체의 클래스가 Cloneable 인터페이스를 구현하고 있지 않는 경우는,CloneNotSupportedException 가 throw 됩니다. 배열은 모두, 인터페이스 Cloneable 를 구현하고 있는 것이라고 보여지는 것에 주의해 주세요. 구현하고 있지 않는 경우, 이 메소드는 이 객체의 클래스의 새로운 인스턴스를 생성해, 그 필드를 모두, 이 객체의 대응하는 각 필드의 내용으로 초기화합니다. 이것은 대입과 같아, 필드의 내용 자신이 복제되는 것은 아닙니다. 즉 이 메소드는, 객체의 「shallow 복사」를 생성합니다만, 「딥 카피」는 생성하지 않습니다.

Object 클래스 자체는,Cloneable 인터페이스를 구현하지 않기 때문에, 클래스가 Object 인 clone 메소드를 호출하면(자), 실행시에 예외가 throw 됩니다.

반환값:
이 인스턴스의 복제
예외:
CloneNotSupportedException - 객체의 클래스가 Cloneable 인터페이스를 지원하고 있지 않는 경우. clone 메소드를 오버라이드(override) 한 서브 클래스도, 인스턴스를 복제할 수 없는 것을 나타내기 위해서(때문에) 이 예외를 throw 하는 일이 있는
관련 항목:
Cloneable

JDK 1.6 API 상에 설명되는 clone() 메소드의 개요

 

  1. class Something {
        ...
        public Something createClone() {
            Something obj = null;
            try {
                obj = (Something)clone();
            } catch ( CloneNotSupportedException e ) {
                e.printStackTrace();
            }
            return obj;
        } 
    }

 

   newInstance()
 

java.lang.Class 클래스의 newInstance 메소드를 사용하면 Class의 인스턴스(객체)를 기초로 그 Class가 표시하고 있는 클래스의 인스턴스(객체)를 만들 수 있다(인수 없는 생성자가 호출된다).

newInstance

public T  newInstance()


throws
InstantiationException ,


IllegalAccessException
이 Class 객체가 나타내는 클래스의 새로운 인스턴스를 생성합니다. new 식에 빈 상태(empty)의 인수 리스트를 지정했을 경우와 같이, 클래스의 인스턴스가 생성됩니다. 클래스는, 초기화되어 있지 않으면 초기화됩니다.

이 메소드는 확인이 끝난 예외 등, 인수 없음의 생성자 에 의해 throw 된 예외를 보내는 것에 주의해 주세요. 이 메소드를 사용하는 것으로, 그 외의 경우에는 컴파일러에 의해 실행되는 컴파일시의 예외 확인을 효과적으로 우회도로 할 수 있습니다. Constructor.newInstance 메소드는, (확인 끝난) InvocationTargetException 의 생성자 에 의해 throw 된 예외를 랩 하는 것으로, 이 문제를 회피합니다.


반환값:
이 객체가 나타내는, 클래스의 새롭게 할당할 수 있었던 인스턴스
예외:
IllegalAccessException - 클래스 또는 그 인수 없음의 생성자 에 액세스 할 수 없는 경우
InstantiationException - 이 Class 가 abstract 클래스, 인터페이스, 배열 클래스, 원시형, 또는 void 를 나타내는 경우, 클래스가 인수 없음의 생성자 을 보관 유지하지 않는 경우, 혹은 인스턴스의 생성이 다른 이유로써 실패했을 경우
ExceptionInInitializerError - 이 메소드에 의한 초기화가 실패했을 경우
SecurityException - 시큐리티 매니저 s 가 존재해, 이하의 조건의 어떤 것인가가 채워지는 경우
  • s.checkMemberAccess(this, Member.PUBLIC) 의 호출이 이 클래스의 신규 인스턴스의 작성을 허가하지 않는다
  • 호출측의 클래스 로더가 같지 않은지, 현재의 클래스 로더의 상위 클래스 로더와 s.checkPackageAccess() 의 호출이 이 클래스의 패키지에의 액세스를 허가하지 않는다

다음은 newInstance의 예입니다. Something 클래스의 인스턴스 someobj가 있다면 다음 식에서 Something 클래스의 인스턴스를 새롭게 만들 수 있다.

  1. someobj.getClass().newInstance();

 

실제로 newInstance 메소드는 InstantiationException이나 IllegalAccessException을 예외로 제공하기 때문에 try{ } catch() {}로 묶든지 메소드에 throws을 선언해야 한다.

 

이 글은 스프링노트에서 작성되었습니다.

출처 :  http://www.okjsp.pe.kr/seq/307

끔찍한 java 에러입니다.
jdbc연결시 에러입니다.


classes12.zip 이 연결이 안된 경우입니다.

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:297)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
at java.lang.ClassLoader.loadClass(ClassLoader.java:253)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:120)
at getEmp.main(getEmp.java:18)

해결1: classes12.zip을 classes12.jar 로 이름을 바꾼 뒤에 <CATALINA_HOME>/common/lib 에 놓고 재시동


host 주소가 맞지 않은 경우입니다.
또는 listener가 떠있지 않은 상태입니다.

java.sql.SQLException: IO 예외 상황: The Network Adapter could not establish the connection
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:210)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)
at java.sql.DriverManager.getConnection(DriverManager.java:517)
at java.sql.DriverManager.getConnection(DriverManager.java:177)
at getEmp.main(getEmp.java:20)


db명이 틀릴경우입니다. 호스트스트링이라고도 합니다.
java.sql.SQLException:IO 예외 상황: Connectionrefused(DESCRIPTION=(TMP=)(VSNNUM=135290880)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:210)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)
at java.sql.DriverManager.getConnection(DriverManager.java:517)
at java.sql.DriverManager.getConnection(DriverManager.java:177)
at getEmp.main(getEmp.java:20)


아이디와 패스워드가 틀릴경우입니다.
java.sql.SQLException: 널 사용자나 암호가 THIN 드라이버에서 지원되지 않습니다
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)
at oracle.jdbc.dbaccess.DBError.check_error(DBError.java:803)
at oracle.jdbc.ttc7.TTC7Protocol.logon(TTC7Protocol.java:179)
at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:198)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)
at java.sql.DriverManager.getConnection(DriverManager.java:517)
at java.sql.DriverManager.getConnection(DriverManager.java:177)
at getEmp.main(getEmp.java:20)

JDBC(Java Database Connectivity)

= 자바를 이용한 데이터베이스 접속과 SQL 문자으이 실행, 그리고 실행결과 얻어진 데이터의 handling을 제공하는 방법과 절차에 대한 규약

= 자바 프로그램 내에서 SQL 문을 실행하기 위한 자바API

● JDBC API는 표준으로 정해졌기 때문에 DBMS에 무관하게 프로그램을 작성할 수 있다. 그러나 JBDC API는 표준적인 API만 제공할 뿐, 실질적으로 작업을 수행하는 부분은 JDBC 드라이버이다.

실습용 테이블 customer 생성 SQL

● 구성 :

= 자바로 작성되어진 클래스와 인터페이스

= Package : java.sql

● import java.sql.*; 필요.

 

● 목적 : 

= Tool / Database 개발자들을 위한 표준 API를 제공하고 pure 자바 API를 이용하여 데이터베이스 Application을 작성할 수 있게 함.

 

● 특징 : 

= java.sql 패키지 안에는 클래스(Class)보다 인터페이스(Interface)가 많이 존재한다.

미완성 상태의 인터페이스는 내부에 추상 메소드만 가지고 있다. 이를 상속받은(Implements) 클래스가 인터페이스 안에 추상 메소드를 선택적으로 오버라이딩을 통해서 구체화하여 실행시킬 수 있게 된다.

  1. Interface A {
      public abstract void go(); // public abstract 는 인터페이스의 기본 설정이다.
    }
  2.  
  3. Class B inplements A {
       public void go(){ ~~~~~}
    }

 

● 기능

= 데이터베이스와 연결(네트워크 연결? 원격접속)

= SQL문 전송

= 결과 처리

 

 

JDBC를 이용하기 위해서는, DBMS 제조사에서 제공하는 JDBC용 드라이버를 설치해야 한다.

JDBC용 드라이버 다운로드 경로 : http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html

 

SQL 과 관련된 내용은 다음 페이지를 참조하세요. ^^

http://sunfuture.springnote.com/pages/3180626

 

● JDBC 작성 순서

# 실습예제 : JdbcOracle.java JdbcOracle.java (코드보기)

[1]. JDBC Driver 등록 - JDBC Driver Manager : 어떤 DBMS를 사용하게 될 것인지를 알려주는 작업

D:\oracle\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar 파일을 복사해서

= 오라클이 설치된 폴더에서 JDBC에 쓰일 수 있는 JDBC 드라이버들이 jar(자바 압축방식)

= 관련내용 : 위키백과 -  http://en.wikipedia.org/wiki/JAR_(file_format)

= Sun 홈페이지 설명 : http://java.sun.com/javase/6/docs/technotes/guides/jar/jarGuide.html

OJDBC14_install.JPG

Drive:\Program Files\Java\jdk1.6.0_13\jre\lib\ext  에 붙여넣기 하면 된다.

- ext 폴더는 자바 실행기에서 기본으로 검색하는 곳이다.

OJDBC14.JPG

[2]. JDBC 드라이버를 로드한다.

  1. Class.forName("oracle.jdbc.driver.OracleDrver");

 

[3]. DBMS에 커넥션(Connection : 네트워크 연결)을 연다.

※ Dirver Manager의 getConnection()을 이용 - Connection 객체 얻어오기.

  1. Connection conn = DriverManager.getConnection( JDBC_URL, db_user, db_passwd);

 

[4]. SQL을 전송한다.

4.1. Connection 객체의 createStatement()을 이용해서 Statement 객체 얻어내기

  1. Statement stat = conn.createStatement();

4.2. ResultSet 객체의 executeQuery()나 executeUpdate()를 이용해서 SQL문을 DB에 전송(날려~, 보내)

ResultSet rs = stat.executeQuery( SQL -

● 사용 SQL이 Select인 경우 : executeQuery()(타입 : ResultSet)  을 실행하면 ResultSet 객체의 getXXXX() 로 받아주어야 한다. 

● 사용 SQL이 Select 아닌 경우 : executeUpdate()(타입 : integer) 는 ResultSet 객체를 생성하지 않는다.

 

[5]. 결과를 처리한다.

참조 API : http://java.sun.com/javase/6/docs/api/index.html

ResultSet(인터페이스, 소스 : ResultSet.java ) 객체의 getXXXX() 를 이용해서 SQL 문장의 실행결과 얻어내기. (※ XXXX는 Select 하는 컬럼의 속성값에 따라 변경된다).

  1. STRING query = "select name, phone from friends";
    ResultSet rs  = stmt.executeQuery(query);
    while ( rs.next() ){
        String name = rs.getString(1);
        String phone = rs.getString(2);
        System.out.println(name + " | " | phone);
    }

컬럼의 순서를 모를 때에는 getXXXX(" "); 를 하면 된다. 접근속도에 영향을 받을 때에는 Index를 사용한다.

rs.absolute(Index);  index  숫자의 행으로 이동한다.

rs.first(); ResultSet 객체의 처음 행으로 이동한다.

rs.last(); ResultSet 객체의 마지막 행으로 이동한다.

※ getXXXX() 메소드 사용시, DB에 저장된 컬럼의 속성에 맞추어서 getInt(), getDouble(), getString() 등으로 맞춰주어야 한다.

 

[6]. 커넥션을 닫는다.

  1. rs.close();
  2. stmt.close();
  3. con.close();

 

이 글은 스프링노트에서 작성되었습니다.

Java Generic Programming 관련 내용 :

WIKI 사이트 : http://en.wikipedia.org/wiki/Generics_in_Java

SUN 사이트 : http://java.sun.com/developer/technicalArticles/J2SE/generics/index.html


  J2SE 5.0에서 가장 두드러진 특징 중의 하나는 제네릭(Generic) 프로그래밍을 지원한다는 것이다. 제네릭 프로그래밍이란 효율적인 알로그림의 추상적인 형태로 표현하기 위한 프로그래밍 기법이다(Generic Programming is a programming mehod that is based in finding the most abstract representations of efficient algorithms. - Alexander Stepanov 정의, WIKI 사이트 참조).


  자바는 제네릭 프로그래밍을 위해서 제네릭 타입과 메소드를 제공한다. 자바 제네릭 프로그래밍은 기존 C++언어의 템플릿과 유사한 점도 있지만 차이점도 많이 갖고 있다. 이러한 차이점들은 C++ 템플릿에 비해 자바 제네릭 프로그래밍에 여러 가지 장점을 제공한다. 자바 제네릭 프로그래밍은 C++ 의 템플릿에 대해서 다음과 같은 장점을 갖는다.

  • 컴파일 시 타입 체킹 가능 - 자바 제네릭 프로그래밍은 컴파일 시에 타입 체킹이 가능하기 때문에 실행 시에 형변환에서 발생할 수 있는 많은 에러를 방지할 수 있다.

  • 하나의 컴파일 된 코드 생성 - C++의 템플릿은 실제로 사용되는 데이터에 따라 여러 개의 컴파일된 코드를 생성하는 데 비해서 자바는 하나의 컴파일된 코드를 생성한다.

  • 소스 코드 불필요 - C++의 템플릿을 사용하는 경우에 템플릿을 사용하기 위해서는 템플릿 소스 코드가 필요하지만, 자바 제네릭 프로그래밍을 사용하는 경우에는 컴파일된 라이브러리만 존재하면 된다.


● 제네릭 클래스, 인터페이스

자바에서 제네릭 클래스, 인터페이스, 메소드는 '<' 과 '>' 문자를 이용해서 표현한다. 예를 들어, GList라는 제네릭 클래스는 다음과 같은 형태로 정의할 수 있다. 이 때 E는 타입을 표현하기 위해서 사용되며, 포멀 파라미터 타입(Formal parameter type)이라고 한다.

   

제네릭 Glist 클래스 정의

class GLisst<E> {
    void add(E x) {
        ...
    }
    ...
}

  정의된 제네릭 클래스는 생성해서 사용할 수 있다. 이 때 제네릭 클래스를 생성할 때 사용되는 타입( 예 : Integer )을 Actual Type Argument라고 한다. 또한 제네릭 타입 선언을 위해 호출하는 것( 예 : GList<Integer> )을 파라미터화된 타입이라고 한다.


● List 인터페이스 사용

GList<Integer> myList = new GList<Integer>();

  파라미터화된 타입(parameterized type)은 클래스 혹은 인터페이스 이름 C와 파라미터 섹션에 해당되는 <T1, ... , Tn>으로 구성된다. 즉, C<T1, ... , Tn>으로 표현된다. 파라미터화된 타입은 다음과 같은 형태로 선언될 수 있다.


형태 : 파라미터화된 타이(Parameterized type)

Class Or Interface < ReferenceType [, ReferenceType ] >


다음 예는 파라미터화된 타입을 선언하는 것을 보여준다.

파라미터화된 타입

Vector<String>

Seq<Seq<A>>

Seq<String>.Zipper<Integer>

Collection<Integer>

Paint<String, String>


J2SE 5.0 에서 작성된 제네릭 프로그램은 컴파일된 후에 J2SE 1.4의 JVM에서도 실행될 수 있다. 이것은 제네릭 특성을 기존 JVM에서도 호환성 있도록 변환하기 떄문에 가능하다. 이처럼 제네릭 프로그램을 제네릭을 사용하지 않는 형태로 변환하는 것을 타입 제거(Type erasure)라고 한다.


java.util 패키지의 자바 컬렉션(Collection) 클래스들은 기본적으로 제네릭 프로그래밍을 지원하도록 만들어졌다. 예를 들어, java.util 패키지의 Vector 클래스도 제네릭 클래스 형태로 정의되어 있다. 따라서 우리는 Vector 클래스를 제네릭 프로그래밍 방법으로 사용할 수 있다. 다음의 StrinVector.java 예제는 Vector 를 이용해서 제네릭 프로그래밍을 사용하는 방법을 보여준다. 제네릭 프로그래밍을 사용하는 경우에 보다 편리하게 프로그래밍을 작성할 수 있다.


ex) StringVector.java

import java.util.*;

    public class StringVector {

    public static void main( String args[] ) {

    Vector<String> v = new Vector<String>();   // 문자열을 원소로 갖는 백터 객체 v를 생성한다.
    v.addElement("Hello");
    v.addElement("World!!");
    //v.add(5); 컴파일시 에러 발생, 5는 String 타입이 아니다.

    for ( String s : v ) { //for 문을 이용해서 백터에 포함된 원소들을 찾아서 출력한다.
        System.out.println( s );
    }
    }

    }



    ex) NormalVector.java (제네릭 프로그래밍 방법을 사용하지 않았을 경우)

    import java.util.*;


    public class NormalVector {

    public static void main( String args[] ) {
    Vector v = new Vector();   // 문자열을 원소로 갖는 백터 객체 v를 생성한다.
    v.addElement("Hello");
    v.addElement("World!!");
    //v.add(5); 컴파일시 에러 발생, 5는 String 타입이 아니다.
    int n = v.size();
    for ( int i = 0 ; i < n ; i++ ) { //for 문을 이용해서 백터에 포함된 원소들을 찾아서 출력한다.
    String s = (String) v.elementAt( i );
    System.out.println( s )
    }
    }

    }

    제네릭 클래스를 사용할 때 타입 파라메터를 기술하지 않는 경우에 컴파일 시에 경고 메시지가 출력된다. -Xlint 옵션을 이용해서 컴파일 하면, 이 경고 메시지를 볼 수 있다.
    Note: VectorTest.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.


    ex) ValueWrapper.java ( 타입 파라메터 T를 갖고, T 타입의 멤버 필드 value와 value() 메소드를 갖는다.)

    public class ValueWrapper<T> {   // ValueWrapper 클래스는 타입 파라메터 T를 갖는 제네릭 클래스이다.

        private T value;            // value 멤버필드는 T타입이다.

        public ValueWrapper(T value) {    //ValueWrapper 의 생성자,
            this.value = value;
        }

        public T value() {
            return value;                  // value() 메소드는 T 타입의 값을 리턴한다.
        }

        public static void main(String[] args) {
           
            ValueWrapper<String> sf = new ValueWrapper<String>("Hello"); //<String>타입의 ValueWrapper의 객체 sf 생성
            System.out.println( sf.value() );

            ValueWrapper<Integer> si = new ValueWrapper<Integer>(new Integer(10)); // <Integer>타입은 <String>타입이 아니기 떄문에, new로 객체선언 해줘야한다.
            System.out.println( si.value() );

        }
    }


    실행결과( 객체 생성시 타입 파라메터 T를 <String>이나 <Integer>로 설정할 때 다른 값을 출력하는 것을 확인할 수 있다)

    Hello
    10


    자바의 제네릭 프로그래밍은 JVM은 변경하지 않으면서 새로운 기능을 제공한다. 따라서 J2SE 5.0 이전에 작성된 프로그램들과도 호환성이 유지된다. 예를 들어, Vector 클래스는 제네릭 클래스로 정의되어 있지만, 타입을 갖기 않는 다음과 같은 형태로 사용할 수도 있다.

     

    ex) 타입이 없는 경우

    Vector v = new Vector();

     

    이처럼 제네릭 클래스에서 타입 파라미터를 사용하지 않는 것을 로타입(Low Type)이라고 한다. 앞의 예에서 v는 로타입이다. 로타입을 사용하지 않는 경우에는 Object 클래스가 타입 파라메터로 사용된다. 파라미터화된 클래스 타입에서 로타입으로 할당은 가능하지만, 안전하지 않기 때문에 컴파일 시에 경고 메시지를 출력한다.


    ex) Cell.java

    1. class Cell<E> {
          private E value;

          public Cell(E v) {
              value = v;
          }

          public E get() {
              return value;
          }

          public void set(E v) {
              value = v;
          }

          public static void main(String[] args) {
             
              Cell<String> x = new Cell<String>( "abc" ); // <String>타입의 Cell 개체 x 생성
              String value = x.get();                        // 개체x가 생성되면서 데이터 "abc"를 반환하는 get() 이용하여 String value 에 넣는다.
              System.out.println( value );
              x.set( "def" );                                // 개체 x에 "def"를 대입한다.

              Cell y = x;                                    // String 타입을 갖는 Cell 객체 x는 로타입 형태인 y에 값을 할당할 수 있다.
              value = (String) y.get();                    // Y 는 로타입이기 때문에 타입 파라미터로 Object가 사용된다. 따라서 형변환을 해야 value에 값을 할당할 수 있다.
              System.out.println( value ) ;
              y.set( "hello" );

          }
      }

    로 타입을 사용하는 경우에는 컴파일 할 때 경고 메시지가 출력된다.

     

    Cell.java:26: warning: [unchecked] unchecked call to set(E) as a member of the raw type Cell
            y.set( "hello" );
                 ^
    1 warning

     

    제네릭 프로그래밍은 타입을 매개 변수로 사용함으로써 프로그램의 일반성을 높이지만, 때로는 타입 파라미터의 범위를 제한해야 하는 경우도 존재한다. 이러한 필요성 때문에 타입 파라미터는 다음과 같은 형태로 범위를 제한할 수 있다.

     

    ex) 타입 파라미터의 범위 제한

    1. public class C1<T extends Number> { ... }
    2. public class C2<T extends Person & Comparable> { ... }

    C1 클래스를 사용하는 경우에 파라미터로는 Number 클래스의 서브클래스만 가능하다.  C2 클래스의 경우에는 Person 클래스로부터 상속 받으며, Comparable 인터페이스를 구현한 클래스만 타입 파라미터로 사용될 수 있다. 타입 파라미터의 상위 타입을 지정하는 경우에는 부모 클래스를 처음에 오도록 하고, 인터페이스들은 & 를 이용해서 여러개 존재할 수 있다.

    이 글은 스프링노트에서 작성되었습니다.

    http://xrath.com 에서 번역한 내용입니다.

    Java SE 6 한글 문서 : http://xrath.com/javase/ko/6/docs/ko/
    Java SE 6 한글 문서 다운로드 : http://xrath.com/files/jdk-6-docs-ko.zip

    자세한 내용은 http://xrath.com/blog/entry/697 를 참고하세요. ^^

    + Recent posts