HttpClient를 이용해 GET request 보내기


Apache HttpClient를 이용하면 간편하게 HTTP request를 보낼 수 있습니다.

간혹 웹 서버를 만들면서 다른 서버로 보터 request를 보내 response 받아 데이터를 처리해야

할 때가 있는데 이 때 HttpClient를 이용하면 간단하게 구현 가능합니다.



Mavan을 이용한 dependency 설정


<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
	<version>4.4</version>
</dependency>


*Maven과 같은 빌드툴 이용하지 않는다면 https://hc.apache.org/downloads.cgi을 통해 직접 jar파일을 다운 후 

빌드 패스에 추가해주시면 됩니다.



Dependency 설정을 하셨다면 이제 어떤 순서대로 코딩할지 살펴보겠습니다.


1. ClosableHttpClient 인스턴스를 생성

2. HTTP request type에 따른 HttpGet/HttpPost 인스턴스 생성

3. addHeader 메서드를 이용해 헤더정보 추가

4. request를 execute해서 CloseableHttpResponse 얻기

5. response 출력

6. close 메서드를 통해 연결 종료




1. ClosableHttpClient 인스턴스 생성

1
2
3
4
5
6
7
8
9
10
11
public class Httpclient1 {
    
    private static final String USER_AGENT = "Mozila/5.0";
    private static final String GET_URL = "http://www.google.com";    
 
    public static void sendGet() throws ClientProtocolException, IOException {
        
        //http client 생성
        CloseableHttpClient httpClient = HttpClients.createDefault();
    }
}
cs


2. HTTP request type에 따른 HttpGet/HttpPost 인스턴스 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Httpclient1 {
    
    private static final String USER_AGENT = "Mozila/5.0";
    private static final String GET_URL = "http://www.google.com";    
 
    public static void sendGet() throws ClientProtocolException, IOException {
        
        //http client 생성
        CloseableHttpClient httpClient = HttpClients.createDefault();
 
        //get 메서드와 URL 설정
        HttpGet httpGet = new HttpGet(GET_URL);
    }
}
cs



3. addHeader 메서드를 이용해 헤더정보 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Httpclient1 {
    
    private static final String USER_AGENT = "Mozila/5.0";
    private static final String GET_URL = "http://www.google.com";    
 
    public static void sendGet() throws ClientProtocolException, IOException {
        
        //http client 생성
        CloseableHttpClient httpClient = HttpClients.createDefault();
 
        //get 메서드와 URL 설정
        HttpGet httpGet = new HttpGet(GET_URL);
 
        //agent 정보 설정
        httpGet.addHeader("User-Agent", USER_AGENT);
    }
}
cs



여기까지 했으면 이제는 excute메서드를 통해 request를 보내주고 받은 응답을 처리하면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Httpclient1 {
    
    private static final String USER_AGENT = "Mozila/5.0";
    private static final String GET_URL = "http://www.google.com";    
 
    public static void sendGet() throws ClientProtocolException, IOException {
        
        //http client 생성
        CloseableHttpClient httpClient = HttpClients.createDefault();
 
        //get 메서드와 URL 설정
        HttpGet httpGet = new HttpGet(GET_URL);
 
        //agent 정보 설정
        httpGet.addHeader("User-Agent", USER_AGENT);
        
        //get 요청
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        
        System.out.println("::GET Response Status::");
        
        //response의 status 코드 출력
        System.out.println(httpResponse.getStatusLine().getStatusCode());
 
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                httpResponse.getEntity().getContent()));
 
        String inputLine;
        StringBuffer response = new StringBuffer();
 
        while ((inputLine = reader.readLine()) != null) {
            response.append(inputLine);
        }
        
        reader.close();
 
        //Print result
        System.out.println(response.toString());
        httpClient.close();
    }
}
cs



실행결과




*json 데이터를 GET request를 통해 받아와야 하는 경우가 많습니다.

그 때에는 Header 정보인 Content-type에 'application/json'을 추가하고 요청을 보내면 됩니다.


예제코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.IOException;
 
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
 
public class httpclient2 {
    
    private static final String USER_AGENT = "Mozila/5.0";
    private static final String GET_URL = "https://blockchain.info/ko"
            + "/rawblock/0000000000000bae09a7a393a8acd"
            + "ed75aa67e46cb81f7acaa5ad94f9eacd103";
    
    public static void sendGet() throws ClientProtocolException, IOException {
        
        //http client 생성
        CloseableHttpClient httpClient = HttpClients.createDefault();
        
        //get 메서드와 URL 설정
        HttpGet httpGet = new HttpGet(GET_URL);
        
        //agent 정보 설정
        httpGet.addHeader("User-Agent", USER_AGENT);
        httpGet.addHeader("Content-type""application/json");
        
        //get 요청
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        
        System.out.println("GET Response Status");
        System.out.println(httpResponse.getStatusLine().getStatusCode());
        String json = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
        
        System.out.println(json);
        
        httpClient.close();
    }
}
cs


실행결과



참고 : http://www.journaldev.com/7146/apache-httpclient-example-closeablehttpclient

'Java' 카테고리의 다른 글

오버로딩 vs 오버라이딩  (0) 2017.05.16
JAVA 특징와 OOP  (0) 2017.05.12
[Reflect]Refletion의 정의와 동적 메소드 호출  (0) 2017.03.17
[Collection] 동기화된 컬렉션  (0) 2017.03.10
[람다식]메소드와 생성자 참조  (0) 2017.03.08

오버라이딩과 오버로딩


오버로딩와 오버라이딩 모두 자바에서 다형성을 지원하는 방법


오버라이딩


흔히, 재정의라고 불린다.

상속관계에서 하위클래스가 상위 클래스의 맴버로 포함된 메서드를 재정의하여 쓰는 것

메서드의 이름은 같지만 안의 구현부만 다르다.


오버로딩


오버로딩의 종류로는 생성자 오버로딩, 메서드 오버로딩이 있다.

메서드의 이름은 같지만 파라미터 타입, 개수에 따라 여러 메서드를 정의하는 것을 말한다.



예제 코드)




Pen.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package co.kr.javastudy.override;
 
public class Pen {
    
    public String maker;
    public int price;
        
    //생성자 오버로딩
    //01.인자를 하나만 같는 생성자
    Pen(String maker) {
        this.maker = maker;
    }
    
    //02. 인자를 두개 같는 생성자
    Pen(String maker, int price) {
        this(maker);
        this.price = price;
    }
    
    public void write() {
        System.out.println("펜을 쓰다");
    }
}
cs



RedPen.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package co.kr.javastudy.override;
 
public class RedPen extends Pen{
    
    public String color = "red";
    
    RedPen(String maker) {
        super(maker);
    }
    
    @Override
    public void write() {
        System.out.println("빨간 펜으로 쓴다.");
    }
    
    //메서드 오버로딩
    //메서드 이름은 같지만 파라미터가 달라서 가능!
    public void write(String place) {
        System.out.println(place + "에 빨칸펜으로 쓴다");
    }
}
cs



main.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package co.kr.javastudy.override;
 
public class main {
    public static void main(String[] args) {
        
        //생성자 오버로딩
        //생성자 오버로딩을 이용해 다양한 파라미터를 전달하여 객체 생성 가능
        Pen pen = new Pen("모나미"200);
        Pen pen2 = new Pen("BIC");
        
        RedPen pen3 = new RedPen("제브라");
        
        
        //메서드 오버로딩 실행 예
        pen3.write("스케치북");
        pen3.write();
        
    }
}
cs



실행결과


JAVA 소개


미국의 선마이크로시스템즈가 개발한 객체 지향 프로그래밍 언어


특징


1. JRE이 설치되어 있으면 컴퓨터와 운영체제 상관없이 작동 - 운영체제에 독립적

2. 기본 자료형 이외에 모든 요소들이 객체로 표현

3. 캡슐화, 상속, 다형성이 잘 적용된 언어

4. GC(garbage collector)를 통한 자동 메모리 관리

5. 멀티 쓰레드 지원



객체지향프로그래밍(OOP)의 특징


1. 추상화

공통의 속성이나 기능을 묶어 이름을 붙이는 것

클래스를 정의하는 것 자체가 추상화라고 볼 수 있음


2. 캡슐화

데이터 구조와 데이터를 다루는 방법을 묶는 것

클래스 내부를 외부에서는 볼 수 없도록 하는 것 - 은닉화


3. 상속성

상위 클래스를 하위 클래스가 물려받는 것

상속을 이용해 재사용성을 증대시킬 수 있다.


4. 다형성

같은 메세지에 따라 클래스가 다른 행위를 하게 하는 것

이름은 같지만 파라미터에 따라 다른 동작을 하는 메소드들을 만듬

Refletion이란?


투영, 반사라는 사전적 의미

객체를 통해 클래스의 정보를 분석하는 기법을 말한다.


자바에서 동적으로 인스턴스를 생성하기 위해 java.lang.reflet api를 통해 제공하고 있다.

이를 이용하면 동적으로 클래스를 생성할 수 있을 뿐만 아니라, 클래스의 메소드를 실행할 수 있다.


예제코드)


다음과 같은 클래스가 있다고 가정


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class TargetClass {
    
    /*
    * reflection 되어질 객체
    */
 
    public void firstMethod() {
        System.out.println("첫번째 매소드");
    }
    
    public void secondMethod(String name) {
        System.out.println("두번째 메소드");
    }
    
    public void thirdMethod(int n) {
        for(int i=0;i<n;i++) {
            System.out.println("세번째 메소드");
        }
    }
}
cs



클래스의 이름을 입력하여 클래스를 찾고 클래스의 선언된 메소드들 찾기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.lang.reflect.Method;
 
public class ReflectionExample {
    public static void main(String[] args) {
        
        /*
         * 클래스의 선언된 메서드를 찾는 방법
         */
        
        try {
            Class targetClass = Class.forName("co.kr.javastudy.reflection.TargetClass");
//java.lang.Class의 forName()메소드를 통해 클래스를 찾음
            
Method methods[] = targetClass.getDeclaredMethods();
            //getDeclaredMethods()를 통해 해당 클래스의 메소드들을 찾음
for(int i=0;i<methods.length;i++) {
                System.out.println(methods[i].toString());
            }
        } catch (ClassNotFoundException e) {
            System.out.println("클래스를 찾을 수 없습니다.");
        }
    }
}

cs



클래스의 선언된 메소드들의 이름 출력


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.lang.reflect.Method;
 
public class ReflectionExample2 {
    public static void main(String[] args) {
        
        /*
         * 클래스의 선언된 메서드이름을 출력
         */
        
        try {
            Class targetClass = Class.forName("co.kr.javastudy.reflection.TargetClass"); 
            Method methods[] = targetClass.getDeclaredMethods(); 
          
            for(int i=0;i<methods.length;i++) {
                String findMethod = methods[i].getName(); //method의 이름 추출
                System.out.println(findMethod);
            }
        } catch (ClassNotFoundException e) {
            System.out.println("클래스를 찾을 수 없습니다.");
        }
    }
}
cs



찾은 메소드를 동적으로 호출


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
public class ReflectionExample3 {
    public static void main(String[] args) {
        
        /*
         * 이름을 지정해 특정 메소드를 실행시키는 방법
         */
        
        try {
            TargetClass target = new TargetClass(); //해당 클래스의 인스턴스 생성
            Class targetClass = Class.forName("co.kr.javastudy.reflection.TargetClass");
            Method methods[] = targetClass.getDeclaredMethods();
            
            for(int i=0;i<methods.length;i++) {
                String findMethod = methods[i].getName();
                if(findMethod.equals("secondMethod")) {
                    //secondMethod를 찾아서 실행
                    try {
                        methods[i].invoke(target,"리플렉션");
                        //invoke()를 통해 메소드 호출 가능
                        //첫번째 파라미터는 해당 메소드를 가진 인스턴스, 두번쨰 파라미터는 해당 메소드의 파라미터
                    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            System.out.println("클래스를 찾을 수 없습니다.");
        }
    }
}
cs



** 리플렉션을 통해 파라미터, 부모 클래스, 패키지, Modifier, Fields, Annotaion 등 다양한 정보를 알아낼 수 있다.

자세한 것은 java api문서를 참고하면 좋을 것 같다.

'Java' 카테고리의 다른 글

오버로딩 vs 오버라이딩  (0) 2017.05.16
JAVA 특징와 OOP  (0) 2017.05.12
[Collection] 동기화된 컬렉션  (0) 2017.03.10
[람다식]메소드와 생성자 참조  (0) 2017.03.08
[람다식] 클래스 멤버와 로컬변수의 사용  (0) 2017.02.24

동기화된 컬렉션


컬렉션 프레임워크의 대부분의 클래스들은 싱글 스레드 환경에서 사용할 수 있도록 설계되어있음

그렇기에 여러 스레드가 동시에 컬렉션에 접근한다면 의도하지 않게 데이터가 변경될 수 있는

불안정한 상태가 된다.



synchronizeList(List<T> list) - list를 동기화된 list로 리턴

synchronizeMap(Map<K, V> map) - map을 동기화된 map으로 리턴

synchronizeSet(Set<T> set) - set을 동기화된 set으로 리턴


ArrayList, HashSet, HashMap이 대표적으로 싱글스레드 기반으로 설계된 컬렉션 클래스인데,

이를 멀티 스레드 환경에서 쓸 수 있도록 컬렉션 프레임워크는 비동기화된 메소드를 동기화된

메소드로 래핑하는 synchronizeXXX( ) 메소를 제공한다.



예제코드


1
2
// 리스트를 동기화된 리스트로 변환
List<T> list = Collections.synchronizedList(new ArrayList<T>());
cs


1
2
// map를 동기화된 map으로 변환
Map<K,V> map = Collections.synchronizedMap(new HashMap<K,V>());
cs


1
2
// set를 동기화된 set으로 변환
Set<T> set = Collections.synchronizedSet(new HashSet<T>());
cs


람다식 메소드 참조


메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어,

람다식에서 불필요한 매개변수는 제거하는 것



사용법 예시)

두수를 입력받아 큰 값을 리턴하는 Math 클래스의 max메소드


1
2
3
4
5
6
7
8
//Math클래스의 max() 참조 방법
 
//람다식은 단순히 두 개의 값을 max메소드에 전달하는 역활만 함.
(x, y) -> Math.max(x, y)
 
 
//메소드 참조를 이용한 람다식 표현
Math :: max
cs



예제코드


1
2
3
4
5
6
7
8
9
10
11
12
public class Calculator {
    //정적 메소드
    public static int staticMethod(int x, int y) {
        return x + y;
    }
 
    //인스턴스 메소드    
    public int instanceMethod(int x, int y) {
        return x + y;
    }
}
 
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MethodReferencesExample {
    public static void main(String[] args) {
        IntBinaryOperator operator;
        
        //정적 메소드 참조
        operator = (x,y) -> Calculator.staticMethod(x, y);
        System.out.println("결과 1 : " + operator.applyAsInt(1,2));
        
        operator = Calculator :: staticMethod;
        System.out.println("결과 2 : " + operator.applyAsInt(3,4));
 
        //정적 메서드는 '클래스명 :: 정적메서드' 형태로 참조 가능
        
        //인스턴스 메서드 참조
        Calculator obj = new Calculator();
        operator = (x,y) -> obj.instanceMethod(x, y);
        System.out.println("결과 3 : " + operator.applyAsInt(5,6));
        
        operator = obj :: instanceMethod;
        System.out.println("결과 3 : " + operator.applyAsInt(7,8));
    }
}
cs




람다식 생성자 참조


생성자 참조도 같은 방법으로 가능하다.



예제코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.function.BiFunction;
import java.util.function.Function;
 
public class ConstructorReferenceExample {
    
    /*
     * 람다식에서의 생성자 참조 "클래스명 :: new"
     */
    
    public static void main(String[] args) {
        Function<String, Member> function1 = Member :: new;
        //매개변수 1개
        Member member1 = function1.apply("dong1");
        
        BiFunction<StringString, Member> function2 = Member :: new;
        //매개변수 2개
        Member member2 = function2.apply("길동""dong1");
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Member {
    private String name;
    private String id;
    
    public Member() {
        System.out.println("기본 생성자");
    }
    
    public Member(String id) {//매개변수 1개
        System.out.println("Member(String id) 실행");
        this.id = id;
    }
    
    public Member(String name, String id) { //매개변수 2개
        System.out.println("Member(String name, String id) 실행");
        this.name = name;
        this.id = id;
    }
}
cs


클래스 멤버와 로컬변수 사용


클래스 멤버 사용


람다식 실행 블록은 클래스의 멤버인 필드와 메소드를 제약없이 사용가능

하지만 주의할 것은 this 키워드!!

일반적인 익명 객체 내부에서는 this는 익명 객체의 참조이지만

람다식에서는 실행한 객체의 참조임


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public interface MyFunctionInterface {
    public void method();
}
 
 
public class UsingThis {
    public int outterField = 0;
    
    class Inner {
        int innerField = 10;
        
        void method() {
            MyFunctionInterface fi = () -> {
                //outterField를 참조하기 위한 방법
                System.out.println("outerField : " + outterField);
                System.out.println("outerField : " + UsingThis.this.outterField);
                
                //innerField를 참조하기 위한 방법
                System.out.println("innerField : " + innerField);
                System.out.println("innerField : " + this.innerField);
            };
            fi.method();
        }
    }
}
 
 
public class UsingThisExample {
    public static void main(String[] args) {
        UsingThis usingThis = new UsingThis();
        UsingThis.Inner inner = usingThis.new Inner();
        inner.method();
    }
}
cs



로컬변수 사용


로컬변수는 제한 없이 사용가능

그러나 사용 변수는 final 특성을 가지게 되어 변경 불가능하게 된다.

타켓타입과 함수적 인터페이스


자바는 메소드를 단독으로 선언할 수 없고 클래스의 구성 멤버로 선언된다.

그렇기에 람다식은 단순히 메소드를 생성하는 것이 아니라 이 메소드를 가지고 있는 객체를 생성하는 것!!


람다식이 생성하는 객체는 인터페이스의 익명 구현 객체

인터페이스를 구현하는 것이기 때문에 람다식은 인터페이스의 종류에 따라 작성방법이 달라진다.

람다식이 대입될 인터페이스가 람다식의 타겟 타입


함수적 인터페이스


람다식은 하나의 메소드를 정의하기 때문에 두 개 이상의 추상 메소드가 선언된 인터페이스는

람다식의 타겟 타입이 될 수 없다.


하나의 추상 메소드가 선언된 인터페이스만이 람다식의 타겟 타입이 될 수 있고,

이러한 인터페이스를 함수적 인터페이스라고 부름


@FunctionalInterface

함수적 인터페이스를 작성할 때 두개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 체크해주는 기능으로

인터페이스 선언시 @FunctionalInterface 어노테이션을 붙이면 됨


1
2
3
4
5
@FuntionalInterface
public interface MyFunInterface {
    public void method();
    public void method2(); //컴파일 오류
}
cs



매개 변수와 리턴갑이 없는 람다식


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@FunctionalInterface
public interface MyFuntionalInterface {
    public void method();
}
//함수적 인터페이스
//이 인터페이스의 추상메서드는 매개변수와 리턴값이 없기 때문에
//이 인터페이스를 타겟 타입으로 갖는 람다식은 매겨변수와 리턴값이 없어야 함 
 
 
public class MyFuntionalInterfaceExample {
    public static void main(String[] args) {
        MyFuntionalInterface fi;
        
        fi = () -> {
            String str = "method call_1";
            System.out.println(str);
        };
        fi.method();
        
        fi = () -> System.out.println("method call_2");
        fi.method();    
    }
}
cs




매개 변수와 리턴값이 있는 람다식


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@FunctionalInterface
public interface MyFuntionalInterface2 {
    public int method(int x, int y);
}
 
//타겟타입이 될 인터페이스
//추상메서드의 리턴값은 int, 매개변수는 두개
//이 인터페이스를 타겟 타입으로 갖는 람다식은
//리턴값 int를 가져야하며 매개변수가 두개여야 한다.
 
public class MyFuntionalInterfaceExample2 {
    public static void main(String[] args) {
        MyFuntionalInterface2 fi;
        
        fi = (x, y) -> {
            int result = x + y;
            return x + y;
        };
        System.out.println(fi.method(23));
        
        fi = (x, y) -> x + y; 
        System.out.println(fi.method(23));
    }
}
 
cs





표준 API 함수적 인터페이스 종류


*자바 8부터 자주 사용되는 함수적 인터페이스를 java.util.funtion에서 제공하고 있음

람다식



람다식이란? 



람다식 등장 배경


람다식은 함수적 프로그래밍을 위해 자바8부터 지원하기 시작


함수적 프로그래밍이 부각되는 이유는 병렬처리와 이벤트 지향 프로그래밍에 적합하기 때문이다.



람다식이란?


람다식은 익명함수를 생성하기 위한 식으로 객체 지향 언어보다는 함수 지향 언어에 가깝다.

람다식을 사용하면 코드가 간결해지고, 컬랙션의 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계 가능



람다식의 형태


매개변수를 가진 코드 블록 --> 런타임 시에는 익명 구현 객체를 생성


1
2
3
4
5
6
7
8
9
Runnable runnable = () -> { ... };
//람다식
 
 
Runnable runnable = new Runnalble() {
    public void run() { ... }
};
// 익명 구현 객체
// 람다식이 런타임시에는 익명 구현 객체로 생성
cs

 



람다식 기본 문법


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
(int a) -> { System.out.println(a); }
//기본 람다식
 
(a) -> { System.out.println(a); }
//매개변수 타입은 런타임시 대입되는 값에 따라 자동으로 인식이 가능
//그렇기에 람다식에서는 매개변수 타입을 일반적으로 언급안함
 
-> System.out.println(a);
//하나의 매개변수만 있다면 괄호 생략가능
//마찬가디로 하나의 실행문만 있다면 중괄호 생략가능
 
(x, y) -> { return x + y; };
(x, y) -> x + y
//중괄호에 리턴문만 있다면 return을 사용하지 않는게 정석 
cs



제너릭 타입도 다른 타입과 마찬가지로 부모클래스가 될 수 있다.


특징

자식 제너릭타입에 타입 파라미터를 추가 가능!



Product라는 제너릭타입이 있다.


1
2
3
public class Product<T, M> {
    //생략
}
cs



Product를 상속받은 ChildProduct는 추가로 타입파라미터를 가질수 있다.

1
2
3
4
public class ChildProduct<T, M, C> extends Product<T, M> {
            //제너릭 타입을 상속받을 때 자식은 추가 타입 파라미터를 가질수 있다.
    //생략..
}
cs


+ Recent posts