VUE.JS


vue 설치 방법은 여러가지가 있다.

CDN 을 추가 하여 사용하는 방법과 CLI 로 설치하는 방법이 있다. 


이번에는 CLI로  설치하는 방법을 리뷰! 


CLI 로 설치하려면 node 패키지인 nmp 이 선행으로 설치되어야 한다. 

CLI 로 설치시 프로젝트 템플릿이 4가지가 있다.

그중 webpack 템플릿 프로젝트를 생성하였다. 


#nmp 설치 또는 최신 업데이트

$ npm install 


#vue - cli  설치

npm install --global vue-cli


#webpack 템플릿을 이용한 프로젝트 생성

$ vue init webpack my-project 



# 의존성을 설치후 실행한다. eslint, router 등등 설정값 (저는 모두 추가함) 

$ cd my-project

$ npm install


#개발환경에서는 dev 로 실행시킨다. 실환경에선 build 로 하면된다.

$ npm run dev



실행하면 포트번호가 자동으로 설정되어 my-project 실행되며 샘플 vue 페이지가 나오게 된다.

이렇게 webpack 프로젝트 생성은 끝 !

Posted by 양승아
:

Spring Batch 개념

FRAMEWORK/Spring 2017. 7. 17. 16:55 |

Spring Batch 개념


- 데이타 프로세싱과 관련된 다양한 방법들을 설정으로 관리할 수 있으며 관련한 통계 정보를 제공(commit 개수, Rollbak, restart ..등)

- 다양한 실행 방법 지원 (command line, Quartz..)

- 각종 읽기와 쓰기 기능의 구성요소를 같은 인터페이스들로 추상화 시키고 있고, 그어 맞는 기본 구현 클래스 제공

- 추가 코딩없이 설정만으로 기존 모듈 활용 가능

- 유연한 Exception 처리





시스템 내의 Soc(Separation of Concern)을 위해 논리적으로 티어 구분을 한다. 

개념 적으로 구분했지만, 논리적인 컴포넌트 배포를 매핑할 때와 데이터 소스나 타겟과 통합하는데 효율적이다.


- Run 티어 : 스케줄링과 애플리케이션 실행에 관련

- Job 티어 : 일반적으로 배치 잡의 실행을 책임. 연속적으로 배치 Step 을 실행시키고 모든 Step 이 실행되서 정확한 상태에 있고 모든 정책이 정확하게 적용됐는지를 보장

- Application 티어 : 프로그램을 실행하는데 필요한 컴포넌트를 포함, 배치 기능을 수행하는데 적용되는 특정 태스크와 정책을 적용.

- Data 티어 : 데이터베이스, 파일, 큐들을 포함하는 물리적인 데이터 소스와 통합




구성요소 






Job 

하나의 배치작업을 정의, 예를 들어 "API 서버의 사용로그 테이블의 데이타를 로그 분석 시스템으로 옮기는 배치"


Job Instance

배치가 실제 실행되면, 각각의 실행을 Instance 라고 한다. 예를 들어 Batch Job이 매주 한번씩 수행된다고 할때 각각의 수행되는 Batch Job을 Batch Instance 라고 한다. 


Job Execution

배치가 실행될때, 각 배치의 실행시, 실제 수행된 Execution을 정의한다.

예를 들어 Batch job 이 월요일 오전에 수행되었을때, 첫번째 실패하고 두번째에 Retry에 의해 성공했다면 이 각각 다른 Job Execution이 실행되고, 같은 작업을 시도하였기 때문에 같은 Job instance 가 된다.


Job parameter

매번 배치 작업이 수행될때 마다 전달되는 Parameter 이다. 예를 들어 매주 수행되는 배치가 있을때, 시작 시간,데이타를 읽을 범위 들 지정하여 Batch Job Instance 를 생성한다면, 이렇게 넘어가는 인가가 JobParamer 이다




Spring 에서 Batch Job 구성


Step 

Spring 에서 Batch Job 은 Step의 모음으로 구성된다. Job 은 Step이 순차적으로 수행되게 된다.


Tasklet 

Tasklet은 각 Step 에서 수행되는 로직이다. 개발자가 custom logic 을 만들수 있고 또는 보통 Batch 의 경우 데이타를 ETL(Extract Transform Loading)하는 형태이기 때문에 ,Spring Batch에서 미리 정의해놓은 Reader, Processor, Writer interface 를 사용할 수 있다.


ItemReader - 데이타를 읽는 컴포넌트

ItemProcessor - 읽은 데이타 처리

ItemWriter - 처리한 데이타를 저장







'FRAMEWORK > Spring' 카테고리의 다른 글

스프링 환경설정 java 버전  (0) 2016.10.05
Spring scheduler 설정 및 사용  (0) 2016.04.12
스프링 이클립스 연동하기  (0) 2015.10.20
aop 예제  (0) 2015.08.24
aop  (0) 2015.08.23
Posted by 양승아
:

MongoDB 설치

카테고리 없음 2017. 6. 16. 17:23 |

MongoDB 


특징

1. NoSQL 데이터베이스의 도튜먼트 스토어

2. JSON 친화적인 데이터베이스

3. 가용성 , 분산가용성 중점

4. 스키마 필요없음

5. 애자일 기반의 개발에 적합함




설치 (OS-window)

https://www.mongodb.com/download-center#community 접속하여 사용자 OS에 맞게 다운로드후 설치 진행한다.

install 이 다 완료된 후에 압축해제하고 폴더명을 mongodb라고 변경해준다.

설치된 루트에 data/db 폴더 생성해준다.(윈도우경우  C/data/db)


설치가 확인하기 위해 명렁어프롬프트 또는 (맥은 터미널) 에서 C:/mongodb/bin/mongod.exe  실행한다.

아래와 같이 실행되면 잘 설치된거다.



Posted by 양승아
:

[java]Mockito 기본 설명

JAVA 2017. 5. 24. 18:36 |

Junit + Mockito


Junit 의 mock 중에 많이 사용되고 업데이트가 잘 이루어지고 있는 것에는 EasyMock, JMock, Mockito 가 있는데

이중 Mockito가 가장 간결한 코드로 테스트를 할 수 있다. 


verify() 

verify()을 이용하여 mock 객체에 대한 원하는 메소드가 특정조건으로 실행되었는지 검증할 수 있다.

mock 작업이 수행되었는지 검증한다. verify(T mock).method();

// mock
List mockedList = mock(List.class);

// mock 사용하기
mockedList.add("one");
mockedList.clear();

// verification
verify(mockedList).add("one");
verify(mockedList).clear();


VerificationMode의 값을 리턴해 주는 메소드는 다섯가지가 있다. 

verify(T mock, VerificationMode mode).method()

----------------------------------------------------------------------------

atLeastOnece();  적어도 한번 수행했는지 검증

atLeast(int n);    적어도 n 번 수행 했는지 검증

times(int n);      무조건 n번 수행했는지 검증 (n보다 크거나 작으면 오류로 간주)

atMost(int n);    최대한 n 번 수행했는지 검증

never();            수행되지 않았는지 검증(수행했으면 오류로 간주)

@Test
public void verifyTest() {
@SuppressAjWarnings("unchecked")
List<String> testMock = mock(ArrayList.class);
testMock.add("1");
testMock.add("2");
testMock.add("3");

// add()가 최소한 1번 이상 호출되었는지 검증
verify(testMock, atLeastOnce()).add(anyString());
// add()가 최소한 3번 이상 호출되었는지 검증
verify(testMock, atLeast(3)).add(anyString());
// add()가 최대한 3번 이하 호출되었는지 검증

verify(testMock, atMost(3)).add(anyString());
// add() 3번 호출되었는지 검증

verify(testMock, times(3)).add(anyString());


verify(testMock, times(1)).add("1"); // add("1") 1번 호출되었는지 검증

verify(testMock, times(1)).add("2"); // add("2") 1번 호출되었는지 검증

verify(testMock, times(1)).add("3"); // add("3") 1번 호출되었는지 검증


// add("4")가 수행되지 않았는지를 검증
verify(testMock, never()).add("4");

InOrder inOrder = inOrder(testMock); //mock 순서 다르게 verify 정의하면 오류난다.

inOrder.verify(testMock).add("1"); //순서 알수있음
inOrder.verify(testMock).add("2"); //순서 알수있음
inOrder.verify(testMock).add("3"); //순서 알수있음

}



when()

제대로 된 mock의 역할을 수행하기 위해서는 원하는 값을 리턴하는 기능도 제공되어야한다.

그럴때 사용하는 메소드가 when이다. when()메소드는 Mock이 감싸고 있는 메소드가 호출되었을 때 ,Mock객체의 메소드(행위)를 호출 선언할때 사용한다.

when() 메소드는 OngoingStubbing 이라는 인터페이스를 리턴한다.


OngoingStubbing 의 메소드

thenAnswer(Answer<?> answer): Answer라는 인터페이스를 구현하며, 원하는 작업을 수행 할 수 있다.

  • thenCallRealMethod(): 해당 메소드가 구현되어 있다면, 실제 메소드를 호출한다.
  • thenReturn(T value): 지정한 값을 리턴한다.
  • thenReturn(T value, T... values): 지정되어 있는 값을 순차적으로 리턴한다.
  • thenThrow(java.lang.Throwable... throwables):  예외를 야기시키는 Throwable 객체를 지정한다. 


@RunWith(MockitoJUnitRunner.class)
junit테스트 사용시 Mockito에서 제공하는 목객체를 사용하기위해 위와같이 어노테이션을 테스트 클래스위에 정의해주면 된다.(목객체 생성할 특정 빈이나 객체가 없다면 목객체는 필요없다.)

@RunWith(MockitoJUnitRunner.class)
public class UserTest{

}


@Mock
mock 인스턴스를 생성하여 목객체를 만들었는데 @mock 어노테이션을 이용해서 mock 객체 생성한다.
User user = mock(ArrayList.class);

위 코드를 아래처럼 사용하면 목 객체 생성. 

@Mock
private User user;



@injectMocks
mockito 에서는 injectMocks 어노테이션을 제공하는데 @Mock,@Spy 이 붙은 목객체를 자신의 멤버 클래스와 일치하면 주입시킨다.  
쉽게 말해 실제 테스트할 클래스가 @injectMocks어노테이션을 사용해 목객체를 생성한다.
테스트할 클래스 안에 또 다른 객체를 생성해야된다면 해당 객체를 @Mock 사용하여 목객체 생성하여 테스트한다.
예제를 보자.

public class AuthService{
private com.neowiz.nsis.mob.web.AuthDao dao;
// some code...
public boolean isLogin(String id){
boolean isLogin = dao.isLogin(id);
if( isLogin ){
// some code...
}
return isLogin;
}
}
public class AuthDao {
public boolean isLogin(String id){ //some code ... }
}

@Mock

AuthDao dao;

@InjectMocks
AuthService service;

@Test
public void example(){
MockitoAnnotations.initMocks(this);
when(dao.isLogin(eq("JDM"))).thenReturn(true);
assertTrue(service.isLogin("JDM") == true);
assertTrue(service.isLogin("ETC") == false);
}




@Before @After
메소드위에 선언되면 해당 테스트 클래스 안에서 메소드들이 테스트되기 전,후에 초기화를 실행하는 어노테이션이다.
private ModelAndView mnv;

@Before
public void setUp() throws Exception {
mnv = new ModelAndView();
}
mvn 객체는 테스트하기전에 초기화되서 매번 정의할 필요없이 테스트 메소드에서 사용 가능 하다. 



assertThat() - hamcrest 
junit 테스트시에 다양한 조건의 match rule 을 손쉽게 작성하고 테스트 할수 있다.(가독성이 더 좋음!!)
assertThat() 뒤에 하나 또는 여러개의 matchers를 사용하여 테스트결과를 확인할 수 있다.


public class CalculatorTest {
Calculator calculator = new Calculator();
@Test
public void testAdd() {
int result = calculator.add(4, 6);
assertThat(result, is(10));
}
}

junit 기본매쳐 링크 클릭하면 된다.








'JAVA' 카테고리의 다른 글

java StringTokenizer  (0) 2015.12.29
Posted by 양승아
:

ROLLUP


롤업구문은 GROUP BY 절과 같이 사용된다.

GROUP BY절에 의해서 그룹지어진 집합 결과에 대해서 좀 더 상세한 정보를 얻을수 있다.

SELECT 절에 ROLLUP을 사용하면 데이터의 총계를 구할수 있다.



TEST_JOB 데이터로 예제를 만들어 보자

SELECT
*
FROM TEST_JOB
ORDER BY JOB;

TEST_JOB 조회시 결과




GROUP BY 를 사용해서 직업별로 급여 합계를 구해보자

SELECT
JOB
,SUM(SAL)
FROM TEST_JOB
GROUP BY JOB;

결과를 보면 JOB별 SAL 의 합계가 조회된다.



ROLLUP 을 사용해서 JOB별 SAL합계와 총계를 구해보자.

SELECT
JOB
,SUM(SAL)
FROM TEST_JOB
GROUP BY ROLLUP (JOB);

결과를 보면 급여합계의 총계가 추가되었다.



ROLLUP을 이용하여 부서별 SAL의 소계와 총계를 구해보자.

SELECT
DEPTNO
,JOB
,SUM(SAL)
FROM TEST_JOB
GROUP BY ROLLUP (DEPTNO,JOB);

결과 



GROUPING()

소계,합계를 구분하고자 할때 GROUPING(컬럼) 또는 GROUPING_ID(컬럼1,컬럼2)를 사용한다. 

GROUPING()함수는 해당 컬럼이 집합에 참여하지 않으면 1을 반환, 집계계산에 참여하면 0을 반환한다.


SELECT
DEPTNO
,JOB
,SUM(SAL)
,GROUPING(DEPTNO)
,GROUPING(JOB)
,GROUPING_ID(DEPTNO,JOB)
FROM TEST_JOB
GROUP BY ROLLUP (DEPTNO,JOB);

결과


'DB > ORACLE' 카테고리의 다른 글

oracle sequence 생성,조회  (0) 2017.03.17
oracle index  (0) 2017.01.19
PIVOT 사용  (0) 2017.01.03
ALTER TABLE  (0) 2016.11.28
Posted by 양승아
:

스프링 부트 시작하기(인텔리J사용)


특징

war파일을 사용하지 않고 내장된 embed tomcat 또는 jetty사용가능

Spring Boot 에서 지원하는 start pom 으로 Meven 또는 gradle 간단하게 사용

Spring의 수많은 설정을 자동으로 설정함 (xml설정 필요 없음),autoconfigure 


인텔리J에서 Spring Boot 프로젝트 생성하기

기술적인 관점에서 보면 스프링 MVC로 웹요청 처리, 뷰 템플릿으로 뷰정의, 스프링데이터 jpa로 데이터데이스에 독서 목록을 영속화,

데이터베이스는 일단 내장된  H2 사용하는 자바애플리케이션 코드작성하는 프로젝트 생성해보자.


인텔리J- new project 



인텔리J 에서 Spring Initializr 프로젝트 생성후

아래와 같이 type 에 메이븐 또는 그레이들 프로젝트를 선택한다.(양이는 그레이들 선택)



NEXT후 

Web, Thymeleaf, JPA, H2를 체크 하여 프로젝트 생성하면 완료!

갓 생성된 스프링부트 프로젝트 살펴보면

src/main/java 애플리케이션 코드 작성

src/main/resources 리소스 작성

src/test/resources 테스트 소스

(기존에 사용했던 Spring+gradle 과 같은 구조)


주요파일

build.gradle - 빌드 명세

gradlew - 그레이들 레퍼

DemoApplication.java - 애플리케이션의 부트스트랩 클래스이자 주 스프링 구성 클래스

application.properties - 애플리케이션과 스프링  부트 프로퍼티를 구성하는 데 사용하는 파일


DemoApplication.java 클래스

스프링의 구성 클래스이다.

스프링의 구성을 제거했지만 자동 구성을 활성화하는 최소한의 구성은 해야한다.

아래 코드보면 구성 코드는 단 한줄이다.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}


@SpringBootApplication 은 스프링 컴포넌트 검색, 스프링부트 자동 구성을 활성화한다. 

@SpringBootApplication 은 @Configuration(스프링의자바기반구성클래스 의미), @ComponentScan(검포넌트 검색 기능 활성화,클래스 자동 검색),@EnableAutoConfiguration(자동설정 활성화) 가 포함되어 있는 어노테이션이다. 

이전에는 이세개의 어노테이션을 붙여야 했지만 스프링부트 버젼이 올라가면서   @SpringBootApplication 하나면 충분하다.


main()메소드에서 해당 클래스 참조 하여 StringApplicaion.run 메소드 전달하여 애플리케이션을 실행할 수 있게 한다.

아직 애플리케이션을 하나도 작성하지 않았지만 애플리케이션을 빌드하고 실행 가능.


빌드(인텔리J커멘트창 이용) 

$ gradle bootRun 

(스프링부트 그레이들 플러그인 포함)

  

gradle build

$ java -jar build/libs/readinglist-0.0.1-SNAPSHOT.jar 

(그레이드 빌드후 자바명령으로 실행가능)


명령 실행후 애플리케이션 정상적으로 작동 (localhost:8080 으로 확인하면 404 NotFoundError 페이지 나타나게됨)

양이는 톰캣 로컬 지정하고 셋팅하여 진행하였음.



application.properties 

초기 셋팅시 파일은 완전히 비어있음.

이파일은 선택적이므로 미사용시 파일 삭제해도 무관하다.

잠깐 프로퍼티를 살짝 건드려보자.

server.port=8000

추가하면 내장 톰캣서버가 기본 포트 8080 포트로 수신 대기하게 된다.

다시 실행하면 8000으로 변경된걸 확인할수 있다.

(중요중요)application.properties를 로드하라고 스프링부트에 명시적으로 요청한 적이 없다는 점!!

application.properties가 존재하면 스프링부트가 자동으로 이 파일을 로드하고 그 안에 프로퍼티를 스프링과 애플리케이션 코드를 구성하는 사용할 수 있게 한다.



스프링부트 프로젝트 빌드 파일(build.gradle)

buildscript {
ext {
springBootVersion = '1.5.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {//스프링부트 의존성
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot' //스프링부트 플러그인 적용

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.7

repositories {
mavenCentral()
}


dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa') //스타터 의존성
compile('org.springframework.boot:spring-boot-starter-freemarker')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.0')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}

빌드파일을 살펴보면 스프링 애플리케이션과 크게 다르지 않다는걸 알 수있다.

다만 스프링부트로 개발할 때는 빌드에 푸가로 도움을 주는 세부적인 옵션을 사용한다.


여기까지 스프링부트 갓 생성한 초기 프로젝트에 대해 알아보았다.

'FRAMEWORK > Spring Boot' 카테고리의 다른 글

spring , spring boot 차이  (0) 2019.05.20
Posted by 양승아
:

제네릭 메소드

JAVA/JAVA 2017. 5. 17. 17:08 |

제네릭 메소드(Generic method)


제네릭 메소드에 대해 전에 간단하게 포스팅 했었는데 오라클 레퍼런스 설명 기반으로 포스팅하려고 한다.

제네릭 메서드는 타입매개변수를 가진 메소드이다. 제네릭타입을 선언하는 것과 비슷하지만 타입매개변수의 스코프는 매서드로 제한된다.(?)


제네릭 메서드 문법은 return 타입 전에 <>사이 타입에 타입매개변수를 표기한다.

static generic 메서드를 위해 타입매개변수는 반드시 메서드의 return타입 이전에 위치해야한다.


아래의 코드를 보면

Util 클래스는 두 Pair 객체를 비교하는 generic 메소드를 포함하고 있다. 




public class Util {
    public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}

public class Pair<K, V> {

    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public void setKey(K key) { this.key = key; }
    public void setValue(V value) { this.value = value; }
    public K getKey()   { return key; }
    public V getValue() { return value; }
}

두 메소드를 호출한 문장은 아래와 같다.

Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util.<Integer, String>compare(p1, p2);


Util.<Integer, String>compare(p1, p2);

<>안에 타입을 명시하여 타입인자는 컴파일러가 타입 추론한다. <>안에 타입 명시하지 않고 generic 메서드가

아닌 일반 메서드를 호출해도 타입추혼이 이루어 진다. 




'JAVA > JAVA' 카테고리의 다른 글

jvm 메모리 구조  (0) 2019.04.22
[객체지향] JAVA SOLID 원칙  (0) 2019.02.23
제네릭 개념 알기  (0) 2017.05.16
다형성  (0) 2015.08.28
클라이언트 ip 구하기  (0) 2015.08.13
Posted by 양승아
:

제네릭 개념 알기

JAVA/JAVA 2017. 5. 16. 15:29 |

java 재네릭


재네릭은 클래스 내부에서 사용할 데이터타입을 외부에서 지정하는 기법을 의미한다.

데이터타입을 외부에서 지정하면 장점뭘까?

메소드 선언에 사용되는 파라미터 형식처럼, 타입 파라미터는 다른 입력값을 같은 코드를 재사용 할 수 있는 방법을 제시한다.

다른점은 형식 파라미터는 값이 아니라 입력이다.

타입파라미터는 타입이 입력!


제네릭 없이 캐스팅이 필요한 코드

List list = new ArrayList(); list.add("hello"); String s = (String) list.get(0);


제네릭을 사용하여 코드 작성시,캐스팅이 필요 없어진다.

List<String> list = new ArrayList<String>(); list.add("hello"); String s = list.get(0); // no cast


제네릭을 사용함으로써 일반적인 알고리즘을 구현하도록 지원한다.

generics를 사용하면서 다양한 타입들의 콜렉션을 사용할 수 있고 더 안정적이고 읽기 쉬운 코드를 일반적인 알고리즘으로 구현할 수 있다.


좀더 자세히 알아보자.

아래의 코드를 살펴보자.

class Person<T>{
 public T info; 
}
 public class GenericDemo{
  
  public static void main(String[] arge){
    Person<String> p1 = new Person<String>();
    Person<StringBuilder> p2 = new Person<StringBuilder>();
  } 
}



데이터 타입 결과는 

p1.info = String

p2.info = StringBuilder


각각의 인스턴스를 생성할 때 사용한 <> 사이에 어떤 데이터 타입을 사용했느냐에 달려있다.


클래스 선언부

public T info;


클래스 필드 info의 데이터 타입은 T로 되어있다. 실제로 T라는 데티어 타입은 존재하지 않는다.

이값은 아래 코드의 T에서 정해진다.


제너릭 클래스 선언부

class Person<T>{


제네릭 클래스의 인스턴스 생성부

Person<String> p1 = new Person<String>();

제네릭 클래스의 인스턴스 생성시 <String> 으로 지정하면서 제네릭 T info는 String info 가 된다.


재네릭 사용하는 이유


class StudentInfo{
    public int grade;
    StudentInfo(int grade){ this.grade = grade; }
}

class StudentPerson{
    public StudentInfo info;
    StudentPerson(StudentInfo info){ this.info = info; }
}

class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class EmployeePerson{
    public EmployeeInfo info;
    EmployeePerson(EmployeeInfo info){ this.info = info; }
}
public class GenericDemo {
    public static void main(String[] args) {
        StudentInfo si = new StudentInfo(2);
        StudentPerson sp = new StudentPerson(si);
        System.out.println(sp.info.grade); // 2
        EmployeeInfo ei = new EmployeeInfo(1);
        EmployeePerson ep = new EmployeePerson(ei);
        System.out.println(ep.info.rank); // 1
    }
}


위 코드를 보면 StudentPerson와 EmployeePerson가 중복되는 클래스이다.

f(x) = x 함수 클래스로 x 매개변수를 제네릭 클래스로 구현하여 StudentPerson와 EmployeePerson 클래스중복을 제거해보자.


class StudentInfo{
    public int grade;
    StudentInfo(int grade){ this.grade = grade; }
}
class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T>{
    public T info;
    Person(T info){ this.info = info; }
}
public class GenericDemo {
    public static void main(String[] args) {
        Person<EmployeeInfo> p1 = new Person<EmployeeInfo>(new EmployeeInfo(1));
        EmployeeInfo ei1 = p1.info;
        System.out.println(ei1.rank); // 성공
         
        Person<String> p2 = new Person<String>("부장");
        String ei2 = p2.info;
        System.out.println(ei2.rank); // 컴파일 실패
    }
}

 

기본 데이터 타입과 제네릭

제네릭은 참조 데이터 타입에 대해서만 사용할 수 있다. 기본 데이터 타입에서는 사용할 수 없다. 따라서 아래 코드의 int는 오류난다.

int . char, double ..등등 은 기본데이터로 사용할 수 없다. int 대신 integer 로 대신하여 사용할 수 있다.

class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
    public T info;
    public S id;
    Person(T info, S id){ 
        this.info = info; 
        this.id = id;
    }
}
public class GenericDemo {
    public static void main(String[] args) {
        Person<EmployeeInfo, int> p1 = new Person<EmployeeInfo, int>(new EmployeeInfo(1), 1);
    }
}
 

복수 제네릭

클래스 내에서 여러개의 제네릭을 필요로 하는 경우 아래의 코드를 참조하자.

class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
    public T info;
    public S id;
    Person(T info, S id){ 
        this.info = info;
        this.id = id;
    }
}
public class GenericDemo {
    public static void main(String[] args) {
        EmployeeInfo e = new EmployeeInfo(1);
        Integer i = new Integer(10);
        Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
        System.out.println(p1.id.intValue());
    }
}
 

재네릭 메소드 사용

class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
    public T info;
    public S id;
    Person(T info, S id){ 
        this.info = info;
        this.id = id;
    }
    public <U> void printInfo(U info){
        System.out.println(info);
    }
}
public class GenericDemo {
    public static void main(String[] args) {
        EmployeeInfo e = new EmployeeInfo(1);
        Integer i = new Integer(10);
        Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
        p1.<EmployeeInfo>printInfo(e);
        p1.printInfo(e);
    }
}
 
재네릭 인스턴스 생략 가능하다. 아래와 같이 p1,p2 모두 정상적으로 생성된다.
Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
Person p2 = new Person(e, i);


extends 로 재네릭으로 올 수 있는 데이터 타입을 특정 클래스의 자식으로 제한할 수 있다.

extends는 상속 관계인 클래스 뿐만 아니라 구현(implements)의 관계에서도 사용할 수 있다.

interface Info{
    int getLevel();
}
class EmployeeInfo implements Info{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
    public int getLevel(){
        return this.rank;
    }
}
class Person<T extends Info>{
    public T info;
    Person(T info){ this.info = info; }
}
public class GenericDemo {
    public static void main(String[] args) {
        Person p1 = new Person(new EmployeeInfo(1));
        Person<String> p2 = new Person<String>("부장");
    }
}



제네릭에 대해 기본적인 개념만 살펴보았다.


'JAVA > JAVA' 카테고리의 다른 글

[객체지향] JAVA SOLID 원칙  (0) 2019.02.23
제네릭 메소드  (0) 2017.05.17
다형성  (0) 2015.08.28
클라이언트 ip 구하기  (0) 2015.08.13
java foreach 반복문  (0) 2015.08.13
Posted by 양승아
: