728x90

 

finally 블록을 추가하면 try문에서 return을 해도 무조건 실행된다!

public class Ex4 {

	public static void main(String[] args) {
		try {
			inputScore(101);
		} catch (InvalidScoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// throws로 예외처리의 책임을 상위로 위임함
	public static void inputScore(int score) throws InvalidScoreException {

		if (score < 0 || score > 100) {
        	// 사용자정의 예외클래스로 예외 발생
			throw new InvalidScoreException("0 ~ 100사이의 정수만 입력하셈");
		}
	}

}

// Exception(상위 예외클래스)를 상속하는 사용자정의 예외클래스
class InvalidScoreException extends Exception {

	public InvalidScoreException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

}
728x90

이클립스에서 웹 프로젝트 시 Unable to compile class for JSP: 나

java.lang.ClassNotFoundException 오류가 뜰 때가 있다.

 

[해결법]

첫번째 방법

Project - Clean 

 

두번째 방법

Project - Properties - Java Build Path - Order and Export - JRE System Library 에 체크 후 Apply

 

세번째 방법

Project - Build Automatically 가 체크해제 되어있으면 체크

728x90

추상(abstract)

추상(abstract)는 공통적인 특성을 정의하여 구체적인 부분은 자식클래스에서 정의하도록 하는 것이다.

이때 공통되는 특성을 가진 상위클래스를 추상 클래스, 이를 상속해 구체화하는 서브클래스는 실체화 클래스라고도 한다.

 

추상 클래스

추상 클래스는 new를 하지 못한다. (인스턴스 생성불가)

추상클래스는 멤버변수, 생성자, 일반메서드, 추상메서드를 가질 수 있다.

public class Ex3 {
	public static void main(String[] args) {
    	// Cannot instantiate the type AbstractClass
//		AbstractClass abstractClass = new AbstractClass();
	}
}

 

추상 메소드

서브클래스의 오버라이딩을 강제할 목적으로 정의하는 메서드로 외부에서 호출되지 않는다. 
모양은 동일하고 수행할 코드가 다른 메서드를 서브클래스에서 상속받아 오버라이딩하도록 강제성을 부여한다.

이전에 다형성에서 살펴봤지만 상속관계에서 오버라이딩이 기본적으로 강제되지는 못한다. 하지만 추상을 이용하면 이를 강제할 수 있는 것이다.

rutel.tistory.com/343

 

[JAVA] 다형성 / 다이나믹 바인딩

 [ 클래스의 관계 ]  1. Has-A 관계(포함 관계)  => A has a B = A 가 B 를 가지고 있다 = B가 A에 포함되어 있다.  => 일반적인 클래스의 관계이며, 특정 클래스 내에 다른 클래스를 포함시켜 사용하는 관

rutel.tistory.com

 

추상메소드는 아래와 같이 abstract 키워드를 사용하며 body (중괄호) 가 없이 세미콜론으로 선언한다.

[접근제한자] abstract 리턴타입 메서드명 ( [파라미터...] );

추상메소드는 반드시 추상 클래스 내에서만 정의 가능하다. 단, 모든 추상클래스가 추상메서드를 포함하는 것은 아니다

abstract class AbstractClass {
	public abstract void abstractMethod();
}

 

추상 클래스를 상속하는 클래스

추상클래스를 상속하는 클래스는 반드시 추상메소드를 재정의(override) 해 구현(implements)하거나

// The type SubClass must implement the inherited abstract method 
// AbstractClass.abstractMethod()
class SubClass extends AbstractClass { }	// error!

메소드 재정의(method override)하지 않을 경우 추상클래스로 선언해야 한다.

abstract class SubClass extends AbstractClass { }
728x90

final variable

 

값을 변경할 수 없으며 멤버변수에 초기화 값이 없을 시 (blank final), 생성자를 통해 초기화해야한다.

final 변수 이름은 모두 대문자를 쓰는 것이 기본 코딩스타일이다. (공백이나 단어구분시 언더스코어 _ 사용)

public class Ex {

	public static void main(String[] args) {
		FinalVariable f = new FinalVariable();
//		f.NUM1 = 10;
		f.num2 = 20;
		
		FinalVariable2 f2 = new FinalVariable2(100);
		FinalVariable2 f3 = new FinalVariable2(9098);
		
		System.out.println(f2.NUM1 + ", " + f2.NUM2);
		System.out.println(f3.NUM1 + ", " + f3.NUM2);
	}

}

class FinalVariable {
	final int NUM1 = 10;
	int num2 = 20;
	
	public void setNum() {
//		NUM1 = 99;
		num2 = 99;
	}
}

class FinalVariable2 {
	final int NUM1 = 30;
	final int NUM2;
	
	public FinalVariable2(int nUM2) {		
		NUM2 = nUM2;
	}
}

Output :

30, 100
30, 9098

 

 

final method

: 상속받은 메소드를 그대로 사용해야하며 오버라이딩이 금지된다

class FinalMethod {
	public void normalMethod() {
		
	}
	
	public final void finalMethod() {
		System.out.println("super class method");
	}
}

class SubFinalMethod extends FinalMethod {

	@Override
	public void normalMethod() { }	
	// Cannot override the final method from FinalMethod
//	public final void finalMethod() { }
}

 

final 클래스

: 클래스의 상속(is-a 관계)이 불가능하다.

final class FinalClass {

}

// The type subfinal cannot subclass the final class FinalClass
//class subfinal extends FinalClass {
//	
//}

: 대신 포함관계 (has-a)는 가능

final class FinalClass {
	public void method() {

	}
}

class SubFinalClass {
	FinalClass finalClass = new FinalClass();

	public void method() {
		finalClass.method();
	}
}

 

 

상수(Constant)

불변의 값. static final 키워드를 붙여서 표현
static 키워드에 의해 클래스명만으로 접근이 가능하며 모든 인스턴스가 하나의 값을 공유

class Car {
	private String company;    
	public static final String COMPANY_HYUNDAI = "HYUNDAI";
    
    public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
}

잘못된 값 입력확률을 줄이고 미리 정의된 값을 쉽게 가져다 쓸 수 있다.

public class Ex2 {
	public static void main(String[] args) {		
		Car car = new Car();		
		car.setCompany(Car.COMPANY_HYUNDAI);
		
		if(car.getCompany().equals(Car.COMPANY_HYUNDAI)) {
			System.out.println("현대자동차");
		} 
	}
}

상수는 생성자에서 초기화 될 수 없다. static은 인스턴스 생성전에 초기화되기 때문

728x90

 [ 클래스의 관계 ]

 1. Has-A 관계(포함 관계)
   => A has a B = A 가 B 를 가지고 있다 = B가 A에 포함되어 있다.
   => 일반적인 클래스의 관계이며, 특정 클래스 내에
        다른 클래스를 포함시켜 사용하는 관계
    ex) class A {
     B b = new B();
    }
2. Is-A 관계(상속 관계)
    => A is a B = A 는 B 이다 = A 는 B 를 상속받은 관계이다. (자신 포함)
    => 초등학생은 학생이다 = 초등학생 is a 학생(O)
       컴퓨터는 기계장치이다 = 컴퓨터 is a 머신(O)
       학생은 학생이다 = 학생 is a 학생(O)
    => 스파이더맨은 사람이다(O)
       사람은 스파이더맨이다(X)
    ex) class A extends B {}
  

 [ instanceof 연산자 ]

 - 좌변의 객체(참조변수)가 우변의 클래스 타입(상속관계)인지 판별하는 연산자
 - 주로 if문에 결합하여 판별하는데 사용되며
  판별 결과가 true 이면 형변환이 가능한 관계(업캐스팅 또는 다운캐스팅)
판별 결과가   false 이면 절대로 형변환 불가능
  
 < 기본 문법 >
 if(A instanceof B) {}
 => A는 참조변수(인스턴스), B는 클래스명

 

public class Ex {

	public static void main(String[] args) {		
		SmartPhone sp = new SmartPhone();
		// 참조변수 sp 로 접근 가능한 SmartPhone 객체의 메서드 : 3개
		sp.call();
		sp.sms();
		sp.kakaoTalk();
		
		if (sp instanceof SmartPhone) {
			System.out.println("sp is a smartphone");
		}
		
		System.out.println("=========================");
		
		if (sp instanceof HandPhone) {
			System.out.println("sp is a HandPhone");
			HandPhone hp = sp;
			hp.call();
			hp.sms();			
		}
		else {
			System.out.println("sp is not a HandPhone");
		}
		
		System.out.println("=========================");
		
		HandPhone hp = new HandPhone();
		hp.call();
		hp.sms();
		
		if (hp instanceof HandPhone) {
			System.out.println("hp is a HandPhone");			
			HandPhone handPhone = hp;
		}
		
		System.out.println("=========================");
		
		if (hp instanceof SmartPhone) {
			System.out.println("hp is a SmartPhone");
		}
		else {
			System.out.println("hp is not a SmartPhone");
//			SmartPhone sp2 = (SmartPhone)hp;
		}
		
		HandPhone hp2 = new SmartPhone();
		hp2.call();
		hp2.sms();
		
		if (hp2 instanceof HandPhone) {
			System.out.println("hp2 is HandPhone");			
		}
		if (hp2 instanceof SmartPhone) {
			System.out.println("hp2 is SmartPhone");
			
		    SmartPhone sp2 = (SmartPhone) hp2;
		    sp2.sms();
		    sp2.kakaoTalk();
		}
		else {
			System.out.println("hp2 is not a SmartPhone");
		}
		
		System.out.println("==========================");
		Child c = new Child();
		
//		Parent p = c;
//		p.parentPrn();
		
		if (c instanceof Parent) {
			System.out.println("c is a Parent");
			Parent p = c;
			p.parentPrn();
		}
		
		Parent p2 = new Parent();
		
		if (p2 instanceof Child) {
			System.out.println("p2 is a Child");
		} else {
			System.out.println("p2 is not a Child");
		}
	}

}

// HandPhone 과 Battery 의 관계는 has-a 관계이다.
class Battery {}

class HandPhone {
	Battery better = new Battery();
	
	public void call() {
		System.out.println("전화!");
	}
	
	public void sms() {
		System.out.println("문자!");
	}
}

// HandPhone 과 SmartPhone 의 관계는 상속관계이다.
class SmartPhone extends HandPhone {
	public void kakaoTalk() {
		System.out.println("카톡!");
	}
}

class Parent {
	public void parentPrn() {
		System.out.println("parentPrn");
	}
}

class Child extends Parent {
	public void childPrn() {
		System.out.println("childPrn");		
	}
}

 

 

상속관계의 오버라이딩

 - 슈퍼클래스의 메서드를 서브클래스에서 오버라이딩 하는 경우
   슈퍼클래스의 메서드는 은닉됨  
 

동적 바인딩 (Dynamic Binding)

 - 상속 관계에서 업캐스팅 후 상속된 메서드를 호출하여 실행할 때
   컴파일(번역) 시점에서의 실행 대상과 실제 실행 단계에서의 실행 대상이 달라지는 것(동적으로 변하는 것)
- 참조 변수의 데이터타입과 무관하게 실제 인스턴스에 따라 실행되는 메서드가 달라짐

public class Ex2 {

	public static void main(String[] args) {
		
		Parent2 p = new Parent2();
		p.parentPrn();
		
		p = new Child2(); // 업캐스팅
		// 참조변수 p 는 Parent2 클래스 타입의 변수이지만
		// 저장된 인스턴스 주소는 Child2 클래스 타입의 인스턴스이다.
		// 따라서, 참조변수 p 를 통해 접근하는 실제 인스턴스는 Child2 이므로
		// p.parentPrn() 메서드를 호출하면 실행되는 메서드도 Child2 의 메서드이다!
		p.parentPrn();
	}

}

class Parent2 {
	public void parentPrn() {
		System.out.println("슈퍼클래스의 parentPrn()");
	}
}

class Child2 extends Parent2 {	
	public void childPrn() {
		System.out.println("서브클래스의 childPrn()");
	}

	@Override
	public void parentPrn() {
		System.out.println("서브클래스에서 오버라이딩 된 parentPrn()");
	}	
}

 

다형성(Polymorphism)

- 하나의 참조변수로 여러 인스턴스를 참조하는 것
= 인스턴스를 다양한 형태로 변환하는 것
= 인스턴스를 업캐스팅하여 슈퍼클래스 타입으로 서브클래스의 멤버 접근

 

public class Ex3 {

	public static void main(String[] args) {
		Circle c = new Circle();
		c.circleDraw();
		
		Rectangle r = new Rectangle();
		r.paint();
		
		Triangle t = new Triangle();
		t.design();
		
		System.out.println("===================");
		c.draw();
		r.draw();
		t.draw();
		System.out.println("===================");
		
		Shape s;		
		s = c;
		s.draw();
		
		s = r;
		s.draw();
		
		s = t;
		s.draw();
	}

}

class Shape { // 도형 클래스
	// 공통적으로 도형을 그릴 수 있는 draw() 메서드 정의
	public void draw() {
		System.out.println("도형 그리기!");
	}
}

class Circle extends Shape {
	public void circleDraw() {
		System.out.println("원 그리기!");
	}

	@Override
	public void draw() {
		System.out.println("원 그리기!");
	}
	
}

class Rectangle extends Shape {
	public void paint() {
		System.out.println("사각형 그리기!");
	}
	
	@Override
	public void draw() {
		System.out.println("사각형 그리기!");
	}
}

class Triangle extends Shape {
	public void design() {
		System.out.println("삼각형 그리기!");
	}
	
	@Override
	public void draw() {
		System.out.println("삼각형 그리기!");
		
	}
}

Output : 

원 그리기!
사각형 그리기!
삼각형 그리기!
===================
원 그리기!
사각형 그리기!
삼각형 그리기!
===================
원 그리기!
사각형 그리기!
삼각형 그리기!

 

 

ex) 다형성은 아래와 같이 메소드의 파라미터를 통해서도 활용할 수 있다.

: 파라미터로 Circle, Rectangle, Triangle 인스턴스 전달 -> Shape 타입으로 업캐스팅됨

public class Ex3 {
	public static void main(String[] args) {		
		drawShape(new Circle());
//		drawShape(new Rectangle());  
		polymorphismDrawShape(new Circle());
		polymorphismDrawShape(new Rectangle());
		polymorphismDrawShape(new Triangle());
	}
	
	public static void drawShape(Circle c) {
		c.draw();
	}
	
	public static void polymorphismDrawShape(Shape s) {
		s.draw();
	}
}

class Shape { // 도형 클래스
	// 공통적으로 도형을 그릴 수 있는 draw() 메서드 정의
	public void draw() {
		System.out.println("도형 그리기!");
	}
}

class Circle extends Shape {
	@Override
	public void draw() {
		System.out.println("원 그리기!");
	}
	
}
(...)

ex) 다형성을 배열에 활용하는 경우 (업캐스팅)

	Circle[] cArr = new Circle[3];
		cArr[0] = new Circle();
//		cArr[1] = new Rectangle();
		
		Shape[] sArr = new Shape[3];
		sArr[0] = new Circle();
		sArr[1] = new Rectangle();
		sArr[2] = new Triangle();
		
		for (Shape shape : sArr) {
			shape.draw();
		}

'Study > Java' 카테고리의 다른 글

[JAVA] 추상(abstract)  (0) 2021.03.09
[JAVA] final 키워드 / 상수(constant)  (0) 2021.03.09
JAVA - 파일 내 특정 문자열이 포함된 행을 제거  (0) 2021.02.04
JAVA에서의 데이터 타입  (0) 2021.01.11
자바 - 식별자  (0) 2021.01.06
728x90

사실 이건 자막 파일에서 시간정보만 빼고 추려내기 위해 만든 소스인데

containString을 수정해서 응용하기 나름일 듯 합니다

import java.util.List;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileReadWrite {

	public static void main(String[] args) {
		
		String readPath = "C:\\Users\\rutel\\Downloads\\sub.vtt";
		String newPath = "C:\\Users\\rutel\\Downloads\\sub.txt";
		String containString = "-->";
		
		//파일 객체 생성
        Path path = Paths.get(readPath);
        // 캐릭터셋 지정
        Charset cs = StandardCharsets.UTF_8;
        //파일 내용담을 리스트
        List<String> list = new ArrayList<String>();
        // 새 파일 내용담을 리스트
        List<String> nlist = new ArrayList<String>();
        try{
            list = Files.readAllLines(path,cs);
        }catch(IOException e){
            e.printStackTrace();
        }
        for(String readLine : list){
            //System.out.println(readLine);
        	if (readLine.contains(containString)) {
        		continue;
        	}
        	else {
        		nlist.add(readLine);
        	}
        }
        // 새 파일 내용쓰기
        try{
            //파일 객체 생성        	
            File file = new File(newPath);
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
            
            if(file.isFile() && file.canWrite()){
            	for(String readLine : nlist){
            		//쓰기
                    bufferedWriter.write(readLine);
                    //개행문자쓰기
                    bufferedWriter.newLine();
            	}
                
                bufferedWriter.close();
            }
        }catch (IOException e) {
            System.out.println(e);
        }
        
        System.out.println("작업 완료");
	}

}

'Study > Java' 카테고리의 다른 글

[JAVA] final 키워드 / 상수(constant)  (0) 2021.03.09
[JAVA] 다형성 / 다이나믹 바인딩  (0) 2021.03.08
JAVA에서의 데이터 타입  (0) 2021.01.11
자바 - 식별자  (0) 2021.01.06
자바 NIO 셀렉터  (0) 2017.07.05
728x90

0. 데이터타입 기초

0-1) 비트 ( bit = binary degit )

- 이진수의 하나의 자릿수를 나타내며 0과 1을 의미

- 컴퓨터에서 0은 전류가 흐르지 않는 상태, 1은 그 반대이다.

  또는 0은 거짓, 1은 참을 의미하기도 한다.

 

0-2) 진법 (Base N)

- 수를 셀 때, 자릿수가 올라가는 단위를 기준으로 하는 셈법의 총칭

- 일상에서 가장 보편적으로 사용하는 것은 10진법으로 (0~9의 범위를 가진다)

- 컴퓨터에서 사용하는 진법은 2진법으로 0과 1

- 8진법은 0~7, 16진법은 0~15까지의 수를 사용하는 진법이다.

단, 16진법은 9이후를 10으로 표기하지 않고 A로 표기한다. (A~F)

 

0-3) 진법 변환

- 10진법 -> 2진법 (소인수분해)

몫과 나머지를 쓰고 나머지를 마지막나머지 + 밑에서부터 차례대로 붙여가면 된다.

바꾼 값의 결과는 아래와 같으며 해당 수의 진법 표기는 괄호안에 적는다. (10)은 10진법 표기

 

13 (10) -> 01101 (2)

 

- 8진법 -> 10진법 (자릿수 변환)

 

0307 (8)

(3 x 82) + (0x81) + (7 x 80) = 199 (10)    // 0승은 항상 1

 

0-4) 리터럴

소스코드에서 프로그래머에 의해 직접 입력된 값, 자바에서 실제 처리하는 데이터

 

 

1. 기본 데이터 타입

- 자바에서의 기본테이터 타입 (반대는 참조데이터 타입) 은 아래 8가지이다.

- 타입이름은 모두 소문자임에 유의

- 1Byte 는 8 bit이다.

   즉 0000 0000(2) ~ 1111 1111(2) 의 값을 표현을 가진다.

 

        1Byte    2Byte    4Byte    8Byte
        (8bit)   (16bit)    (32bit)   (64bit)
-----------------------------------------
정수형   byte     short    int      long
실수형                      float    double
문자형              char  --- 실제로 char(캐릭터) 타입은 정수형에 포함되나 이는 뒤에서 설명
논리형  boolean

 

char는 ushort, int, uint, long, uyong, float, double 또는 10진수로 암시적으로 변환될 수 있다. 그러나 다른 유형에서 char 유형으로의 암묵적 변환은 없다.

 

1) 정수형(Interger Type)

저장되는 값의 허용범위 (char타입은 음수값을 포함하지 않으므로 제외)

n = 메모리bit수 - 1   (ex : 8bit크기는 8 - 1 = 7)
  -2^n ~ (2n-1)

byte : -128 ~ 127    | 0포함,  -2^7 ~ (2^7-1)

short : -32768 ~ 32,767

char : 0 ~ 65536 (유니코드) | 0 ~ (2^16-1)

int : 약 -21억 ~ 21억 | -2^31 ~ (2^31-1)

long : 약 -922경 ~ 922경

 

1-2) 정수 리터럴 표현

- 2진수 : 0b1011  (맨앞은 숫자 0)

- 8진수 : 013       (맨앞은 숫자 0)

- 10진수 : 365     (소수점없는 10진법 숫자)

- 16진수 : 0x3B0F (맨앞은 숫자 0)

- long타입 (기본적으로 자바 컴파일러는 정수 리터럴을 int타입으로 간주한다!)

long l = 12_345_678_999;	// int타입으로 간주해서 타입이 맞지 않다는 에러 출력
long l = 12345678999L;   // int타입 범위를 벗어나면 L을 붙여서 롱타입임을 알려줌, 에러 없음

* 숫자밑에 _은 자릿수 구분을 위한 임의 표기로 에러사항이 아님

 

1-3) char타입

작은 따옴표로 감싼 형식을 쓰며 이것을 문자 리터럴이라고 한다.

문자 리터럴엔 유니코드값인 2byte크기 (0~65535)에 세계각국의 문자코드가 변환되어 저장된다.

 

유니코드 값은 크게 a, A, 0 값만 알고 있어도 유용하다.

char타입엔 아래와 같이 정수값을 저장해 쓸 수 있다.

char ch1 = 'A';	// unicode : 65
char ch2 = 65;	// A와 같음
char ch3 = '0'; // unicode : 48
char ch4 = 48;  // 문자 0과 같음
char ch5 = 'a'; // unicode : 97
char ch6 = '97';// a와 같음

아래와 같이 16진수 표현 또는 유니코드 표현을 쓸 수도 있다.

char c1 = 0x0041;	// 10진수값으로 65이며 unicode문자 A
char c2 = '\u0042'; // 문자 B

또한 int타입 변수에도 저장할 수 있지만 이 때는 콘솔로 출력해보면 유니코드 값이 출력된다.

char ch1 = 'A';		// A출력
int i = 'A';		// 65출력

2) 실수 타입

자바에서는 실수 연산은 기본적으로 double 타입으로 처리한다. (정수는 int)

따라서 float타입의 변수 선언 시 반드시 f를 붙여 float형으로 간주하도록 한다.

float f = 3.14f;  // 대문자 F로도 표기 가능, f생략 시 컴파일 에러

 

실수 타입은 항상 정수보다 표현범위가 크다. 

부동 소수점 방식으로 저장되어 더 큰 범위의 값을 저장할 수 있다. 

float : (+/-) 1.4 x10−45 ~ (+/-) 3.4028235 x 1038

double : (+/-) 4.9 x10−324 ~ (+/-) 1.7976931348623157 x 10308

 

0.1 == 0.1f
실수저장방식인 부동소수점 방식이 0.1을 정확히 표현불가 
0.1f는 0.1의 근사값 (.1.......) 따라서 0.1보다 큰값이 됨

 

2. 참조타입

Date today = new Date();

데이터 클래스 타입의 참조형 변수 today선언

참조타입은 4byte를 가진다.

 

문자열을 저장가능한 String 타입또한 클래스 타입의 참조타입이다.

String str = "이것이 문자열입니다.";

 

'Study > Java' 카테고리의 다른 글

[JAVA] 다형성 / 다이나믹 바인딩  (0) 2021.03.08
JAVA - 파일 내 특정 문자열이 포함된 행을 제거  (0) 2021.02.04
자바 - 식별자  (0) 2021.01.06
자바 NIO 셀렉터  (0) 2017.07.05
Java Network 프로그래밍 기초  (0) 2017.06.03
728x90

식별자 (Identifiers)

- 자바에서 각 대상을 구분하는 이름

- 변수, 상수, 클래스, 인터페이스, 패키지 등과 같은 개체(entity)의 이름

 

식별자 작성 규칙
[ 필수 사항 ]
1. 첫글자에 숫자 사용 불가(ex. 7eleven 사용 불가)
2. 특수문자 $ 또는 _ 만 사용 가능(ex. channel#5 사용 불가)
3. 대소문자 구별(ex. name 과 Name 은 다름)
4. 예약어(키워드) 사용 불가
5. 공백 사용 불가

6. 한글 사용도 가능 (권장사항 아니며 실제 사용하지 않음)
--------------------------------------------
[ 권장 사항 ]
6. 길이 제한 없음
7. 의미가 있는 단어 사용
8. 한글 사용 가능(하지만 실제 사용하지 않음 => 문제 발생 가능성 있음)
9. 두 개 이상의 단어를 조합할 경우 두번째 단어부터 첫글자를 대문자 사용
   ex) myfirstname => myFirstName(Camel-case 표기법)

'Study > Java' 카테고리의 다른 글

JAVA - 파일 내 특정 문자열이 포함된 행을 제거  (0) 2021.02.04
JAVA에서의 데이터 타입  (0) 2021.01.11
자바 NIO 셀렉터  (0) 2017.07.05
Java Network 프로그래밍 기초  (0) 2017.06.03
NIO 기반 네트워킹  (0) 2017.05.30
728x90

Server.java




import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.nio.charset.Charset;

import java.util.Iterator;

import java.util.List;

import java.util.Set;

import java.util.Vector;


public class IotServer {

Selector selector;

ServerSocketChannel serverSocketChannel;

List<Client> connections = new Vector<Client>();


void startServer() {

try {

selector = Selector.open();

serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.configureBlocking(false);

serverSocketChannel.bind(new InetSocketAddress(5001));

serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

} catch (Exception e) {

if(serverSocketChannel.isOpen()) { stopServer(); }

return;

}


Thread thread = new Thread() {

@Override

public void run() {

while(true) {

try {

int keyCount = selector.select();

if(keyCount == 0) { continue; }

Set<SelectionKey> selectedKeys = selector.selectedKeys();

Iterator<SelectionKey> iterator = selectedKeys.iterator();

while (iterator.hasNext()) {

SelectionKey selectionKey = iterator.next();

if (selectionKey.isAcceptable()) {

accept(selectionKey);

} else if (selectionKey.isReadable()) {

Client client = (Client)selectionKey.attachment();

client.receive(selectionKey);

} else if (selectionKey.isWritable()) {

Client client = (Client)selectionKey.attachment();

client.send(selectionKey);

}

iterator.remove();

}

} catch (Exception e) {

if(serverSocketChannel.isOpen()) { stopServer(); }

break;

}

}

}

};

thread.start();


System.out.println("서버 멈춤");

}


void stopServer() {

try {

Iterator<Client> iterator = connections.iterator();

while(iterator.hasNext()) {

Client client = iterator.next();

client.socketChannel.close();

iterator.remove();

}

if(serverSocketChannel!=null && serverSocketChannel.isOpen()) { 

serverSocketChannel.close(); 

}

if(selector!=null && selector.isOpen()) {

selector.close();

}

System.out.println("서버 멈춤");

} catch (Exception e) {}

}


void accept(SelectionKey selectionKey) {

try {

ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();

SocketChannel socketChannel = serverSocketChannel.accept();


String message = "[연결 수락: " + socketChannel.getRemoteAddress()  + ": " + Thread.currentThread().getName() + "]";

System.out.println(message);


Client client = new Client(socketChannel);

connections.add(client);


System.out.println("[연결 개수: " + connections.size() + "]");

} catch(Exception e) {

if(serverSocketChannel.isOpen()) { stopServer(); }

}

}



class Client {

SocketChannel socketChannel;

String sendData;


Client(SocketChannel socketChannel) throws IOException {

this.socketChannel = socketChannel;

socketChannel.configureBlocking(false);

SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_READ);

selectionKey.attach(this);

}


void receive(SelectionKey selectionKey) {

try {

ByteBuffer byteBuffer = ByteBuffer.allocate(100);


//상대방이 비정상 종료를 했을 경우 자동 IOException 발생

int byteCount = socketChannel.read(byteBuffer); 


//상대방이 SocketChannel의 close() 메소드를 호출할 경우

if(byteCount == -1) { 

throw new IOException();

}


String message = "[요청 처리: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";

System.out.println(message);


byteBuffer.flip();

Charset charset = Charset.forName("UTF-8");

String data = charset.decode(byteBuffer).toString();

System.out.println(data);

for(Client client : connections) {

client.sendData = data;

SelectionKey key = client.socketChannel.keyFor(selector);

key.interestOps(SelectionKey.OP_WRITE);

}

selector.wakeup();

String[] receivedMessage = null;

receivedMessage = data.split("#");   

System.out.println(receivedMessage[0]+"\n"+receivedMessage[1]);

if(receivedMessage[0].equals("hello")){

if(receivedMessage[1].equals("server")) {

System.out.println("split");

}

}

} catch(Exception e) {

try {

connections.remove(this);

String message = "[클라이언트 통신 안됨: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";

System.out.println(message);

socketChannel.close();

} catch (IOException e2) {}

}

}


void send(SelectionKey selectionKey) {

try {

Charset charset = Charset.forName("UTF-8");

ByteBuffer byteBuffer = charset.encode(sendData);

socketChannel.write(byteBuffer);



selectionKey.interestOps(SelectionKey.OP_READ);

selector.wakeup();

} catch(Exception e) {

try {

String message = "[클라이언트 통신 안됨: " + socketChannel.getRemoteAddress() + ": " + Thread.currentThread().getName() + "]";

System.out.println(message);

connections.remove(this);

socketChannel.close();

} catch (IOException e2) {}

}

}

}


public static void main(String[] args) {

IotServer server = new IotServer();

server.startServer();

}

}



'Study > Java' 카테고리의 다른 글

JAVA에서의 데이터 타입  (0) 2021.01.11
자바 - 식별자  (0) 2021.01.06
Java Network 프로그래밍 기초  (0) 2017.06.03
NIO 기반 네트워킹  (0) 2017.05.30
JAVA - NIO  (0) 2017.05.29
728x90

Java Network 프로그래밍 기초 

( 참고 서적 : 자바 네트워크 프로그래밍 [자바 8과 함께하는 네트워크 애플리케이션 개발] )


IP 주소를 나타내는 InetAddress 클래스


InetAddress 클래스는 public 생성자가 없으므로 여러 static type의 get 메소드 중 하나를 사용한다. (.get~~)

다음은 특정 사이트의 ip주소를 얻는 예제이다. 


1
2
3
4
5
6
7
8
9
import java.net.InetAddress;
import java.net.UnknownHostException;
 
public class Address {
    public static void main(String[] args) throws UnknownHostException {
         InetAddress address = InetAddress.getByName("www.packtpub.com");
         System.out.println(address);
    }
}
cs


결과 : 

www.packtpub.com/83.166.169.231


해당 주소의 접속 여부를 결정하기 위해 필요한 대기시간을 다음과 같이 지정할 수 있다.

isReachable 메소드의 인자는 m/s 단위의 대기 시간이다.


1
 address.isReachable(3000);
cs




NIO 지원



selector : 다중 채널을 처리하기 위한 싱글 스레드를 허용하는 기술




자바 서버와 안드로이드 클라이언트 연동


Server.java 의 전체 소스


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
42
43
44
45
46
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
 
public class Server {
 
    public static void main(String[] args) {
        ServerStart();
    }
 
public static void ServerStart() {
    try {
        int portNum = 11001;
 
        System.out.println("서버 시작이당");
        @SuppressWarnings("resource")
        ServerSocket serverSocket = new ServerSocket(portNum);
        System.out.println(portNum);
 
        while (true) {
            Socket socket = serverSocket.accept();
            InetAddress clientHost = socket.getInetAddress();
            int clientPort = socket.getPort();
            System.out.println("클라이언트 접속, 호스트 : " + clientHost + ", port : " + clientPort);
 
            ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
            Object obj = inputStream.readObject();
            System.out.println("Input : " + obj);
 
            ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
 
            outputStream.writeObject(obj + " 서버로부터 메시지 ");
            outputStream.flush();
            socket.close();
        }
    }
    
    catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}
 
cs



안드로이드 클라이언트


인터넷을 사용하기 위해 AndroidManifest.xml에 유저 권한 추가

<uses-permission android:name="android.permission.INTERNET" />


클라이언트 레이아웃 (activity_main.xml 디자인)




MainActivity.java의 전체 소스

package com.example.pknu.hello;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

EditText input01;
Button button01;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

input01 = (EditText) findViewById(R.id.input01);

// 버튼 이벤트 처리
button01 = (Button) findViewById(R.id.button01);
button01.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String addr = input01.getText().toString().trim();

ConnectThread thread = new ConnectThread(addr);
thread.start();
}
});

}

class ConnectThread extends Thread {
String hostname;

public ConnectThread(String addr) {
hostname = addr;
}

public void run() {

try {
int port = 11001;

Socket sock = new Socket(hostname, port);
ObjectOutputStream outstream = new ObjectOutputStream(sock.getOutputStream());
outstream.writeObject("Hello AndroidTown on Android");
outstream.flush();

ObjectInputStream instream = new ObjectInputStream(sock.getInputStream());
String obj = (String) instream.readObject();

Log.d("MainActivity", "서버에서 받은 메시지 : " + obj);

sock.close();

} catch(Exception ex) {
ex.printStackTrace();
}

}
}
}



'Study > Java' 카테고리의 다른 글

자바 - 식별자  (0) 2021.01.06
자바 NIO 셀렉터  (0) 2017.07.05
NIO 기반 네트워킹  (0) 2017.05.30
JAVA - NIO  (0) 2017.05.29
Java - OOP_인터페이스와 다형성  (0) 2017.03.20

+ Recent posts