2017년 6월 26일 월요일

[Java] 자료형(Data Type)과 변수

자바에서 모든 변수(Variable)는 그에 맞는 Type(형태)를 가지고 있다. 자바에는 총 8개의 원시형(Primitive Type)이 있으며, 정수(Integer)형 4개[int, short, long, byte], 소수(Floating-point)형 2개[float, double], 문자(Character)형 1개[char], Boolean형 1개로 이루어져 있다. 그리고 문자열 형식(String)은 String 객체를 통해 표현한다.

모든 자바의 변수들은 그에 맞는 type(형)을 가진다. 변수의 이름은 언제나 문자로 시작해야하며 문자 1개만 사용해서는 안된다. 다만 '$' 문자는 자바 컴파일러에 의해 사용되기도 하니 사용을 피하도록 하자. 또한 Java reserved word 들은 사용하면 안되는데, 예를들면 int, double, for, if 와 같이 자바에서 구문으로 사용되는것들은 사용할수 없다.

Integer Type(정수형)


정수형이란 소수점 아래로 표현이 불가능한 양수와 음수들을 말한다.


Type저장공간표현 가능 수
long8 bytes-2^63 ~ +2^63
int4 bytes-2^31 ~ +2^31
short2 bytes-2^15 ~ +2^15
byte1 bytes-2^7 ~ +2^7

각 타입의 저장공간에서 가장 첫번째 비트(bit)는 수가 음수인지, 양수인지를 의미하므로, 나머지 비트만큼 수를 표현 할 수 있다. 대부분의 경우에 int 타입이 가장 실용적이며, 이보다 더 큰 수를 저장해야 할 경우에는 long 타입을 이용할 수 있다. short 타입과 byte 타입은 low level file 사용 등의 특별한 경우에 사용된다.

long 타입 정수들은 값의 마지막에 L 또는 l을 붙인다. 16진수들은 수의 첫자리에 0x 또는 0X를 붙이며, 8진수는 수의 첫자리에 0을 붙인다. 또한 Java SE7 부터는 수의 첫자리에 0b, 0B붙이며 2진수로 수를 표현할 수도 있다. 수가 너무 커지거나 길어져서 읽기 힘들면, ','(반점)으로 구분하듯이 '_'(underscore, 밑줄문자)를 이용해 구분할 수도 있다. 이는 단순히 개발자가 쉽게 구분하기 위한 용도이며, 자바 컴파일러는 컴파일시 밑줄문자를 그냥 무시한다.


//값 정의
long lExample1 = 100L, lExample2 = 233l;
int hexaExample1 = 0x143, hexaExample2 = 0X233;
long octExample1 = 010, octExample2 = 034;
int biExample1 = 0b10101, biExample2 = 0B1101;
int million = 1_000_000; // 백만

//값 확인
System.out.println(lExample1);// 100
System.out.println(lExample2);// 233
System.out.println(hexaExample1);// 323
System.out.println(hexaExample2);// 563
System.out.println(octExample1);// 8
System.out.println(octExample2);// 28
System.out.println(biExample1);// 21
System.out.println(biExample2);// 13
System.out.println(million);// 1000000

각 프로세서 별로 맞는 정수형 데이터 타입을 사용해야하는 C, C++와는 달리 자바에서는 그런 걱정을 할 필요가 없다. 이러한 요소는 자바가 Platform-Independent Language(플랫폼 독립 언어)라 불리는 이유 중 하나 이기도 하다.


Floating-Point Type(부동소수형)


말 그대로 소수형이다. 정수형과 달리 소수들도 표현 가능하다. IEEE754 표준에 기초한다.


Type저장공간표현 가능 수
double8 bytes±3.40282347E+38
float4 bytes±1.79769313486231570E+308

double이라는 자료형은 float이 32bit single precision을 쓰고 double 형이 그 2배를 저장할수 있다는 뜻에서 double로 유래됬다. float형 소수는 언제나 숫자 뒤에 F 또는 f가 붙는다. 소수이나 f 또는 F가 붙지 않았다면 double형으로 처리된다. double형에 대해 특별히 표시를 하고 싶다면 D 또는 d를 뒤에 붙이면 된다.

모든 부동소수형(Floating Point) 연산은 IEEE 754기준에 따라 연산된다. 그렇기 때문에 좀 애매한 결과가 나올때도 있는데 예를 들어 "2.0-1.1" 을 연산하게 되면 결과값이 0.9가 나와야 하지만 실제 결과는 0.8999999999999999이 나오게 된다.


이는 2진수에서 10진수로 변환할때 생기게 되는 문제다. 예를들어, 0.5라는 10진수를 2진수로 표현하게 되면 0.1로 표현할 수 있다. 0.75는 0.11이되고, 0.875는 0.111(2^-1 + 2^-2 + 2^-3)이 된다. 2진수 연산이기 때문인데, 그렇기 때문에 모든 분수들은 2의 배수가 분모가 되는 분수들로 표현된다. 우리가 10진수의 세상에서 1/3을 소수형으로 딱 떨어지게 표현하지 못하는것처럼 2진수의 세계에서 1/10을 정확하게 표현하지 못한다. 만약 이런 에러들을 피하고 싶다면 원시 자료형인 double형이나 float형 말고 BigDecimal이라는 클래스를 이용하도록 하자.


System.out.println(2.0-1.1); //0.8999999999999999

BigInteger & BigDecimal


기본적인 정수형과 소수형이 원하는 수를 저장하지 못한다면 자바 라이브러리 java.math 패키지의 BigInteger 클래스와 BigDecimal 클래스를 이용하면 된다.
다만 연산을 위해서는 +,-와 같은 일반 연산자가 아닌 BigInteger, BingDecimal 클래스의 메소드를 이용해야 한다.

BigDecimal a = BigDecimal.valueOf(2.0);
BigDecimal b = BigDecimal.valueOf(0.1);
BigDecimal c = a.divide(b);
System.out.println(c); //20


char Type(문자형)


char형은 말그대로 문자 1개를 표현하기 위해 만들어졌다. 2 byte의 데이터를 저장할 수 있다. char형에 데이터를 어싸인하기 위해서는 작은따옴표('') 사이에 문자 1개를 집어넣어주면 된다. 문자 1개밖에 못저장한다. 2개넣으면 신텍스 에러가 뜬다. 작은따옴표만 사용해야 한다. 아스키(ASCII) 값 65를 가진 알파벳를 어싸인할 때 'A'"A"는 큰 차이가 있다.  작은따옴표('') 사이의 A는 문자형 A 이지만 큰따옴표("")사이의 A 는 String 형 A 이기 때문이다. 그렇기 때문에 큰따옴표를 써도 신텍스 에러가 난다. 유니코드 또는 아스키 코드로 값을 어싸인할수도 있다.


char asciiA = 65; //ASCII 코드 A
char unicodeA = '\u0041'; //UTF-8(유니코드) A
System.out.println(asciiA); //A
System.out.println(unicodeA); //A


boolean Type(boolean형)


boolean 형은 2가지 값 true, false, 둘중 하나밖에 저장하지 못한다. 단순히 논리문의 조건을 저장하기 위해 존재한다.


boolean falseTest = false;
boolean trueTest = true;
System.out.println(falseTest); //false
System.out.println(trueTest); //true

2017년 6월 16일 금요일

아파치 메이븐(Apache Maven) 시작하기

Apache Maven 프로젝트는 Java 어플리케이션의 빌드 과정을 간략화하기 위해 시작된 프로젝트이다. 그 전까지는 Apache Ant 를 이용해서 빌드 했는데, 이 경우에 여러개의 섭프로젝트로 이뤄진 하나의 프로젝트를 진행할 때 각 섭프로젝트가 서로 다른 Ant 빌드 파일을 가지고, 빌드된 JAR 파일들이 만들어지게 된다. Apache 개발팀은 프로젝트를 빌드하는데 있어 프로젝트의 구성 정보를 확실하게 전달하고, 여러 프로젝트에서 쉽게 JAR 파일을 공유할 수 있는 방식의 필요성을 느꼈고, 그에 대한 결과물로 Maven 이 탄생하게 된다. 그러니까 Maven은 기존의 "Ant + @기능들" 이라 생각하면 된다.

Maven을 우선 설치해야 공부하니까 설치하자. 가장 최신버젼은 3.5 버젼이고, 3.3 버젼 이상부터는 JDK 1.7이상이 설치되어있어야 한다. 설치가 안되있다면 [Java] 자바 시작하기(개발 환경 구성) 글을 보고 설차하도록 하자.

그리고 "JAVA_HOME" 이라는 환경변수 설정을 해주자. 위 글을 보고 따라하는 Ubuntu 사용자의 경우에는 나와 같은 위치에 설치했을테니 쉘을 열고 아래와 같이 타이핑하면 된다. 아니면 각기 jdk 설치한 위치로 하자. 윈도우 사용자의 경우에는 내컴퓨터 옵션에서 환경변수를 설정하자.

export JAVA_HOME= /opt/java/jdk1.8 #jdk폴더위치

그리고 나서는 https://maven.apache.org/download.cgi에 들어가 Maven 파일을 다운로드 해주자. 영어로 복잡하게 많겠지만 Link 칼럼에 있는것중에 Binary Archive를 다운받으면 된다. Source라 적힌것들은 직접 개발할때 쓰라는거다.

나의 경우에는 3.5버젼 apache-maven-3.5.0-bin.tar.gz 파일을 받았다. 다운 다 했으면 설치할 위치에 압축 풀고 놔주자. 편한데 놔두면 된다. 나는 /opt 폴더에 놔뒀다.

그리고 maven 폴더의 bin 폴더를 $PATH 변수에 추가해주면 된다. 그리고 쉘에서 mvn -v 명령어를 실행해주면 아래와 같은 결과가 나오고, 그러다면 설치가 완료된것이다.


user@user-desktop:~$ mvn -v
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T04:39:06+09:00)
Maven home: /opt/apache/apache-maven
Java version: 1.8.0_112, vendor: Oracle Corporation
Java home: /opt/java/jdk1.8/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-79-generic", arch: "amd64", family: "unix"

설치를 완료했다면 프로젝트를 하나 만들어보자. 아래 명령어를 실행해준다


user@user-desktop:~$ mvn archetype:generate 
# 첫 실행시 필요한 플러그인들과 파일들을 다운받는라 좀 오래걸릴거다.

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 984: #그냥 엔터치면 기본값으로 설정된다
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
Choose a number: 6: #마찬가지, 엔터
Define value for property 'groupId': com.muckycode.app
Define value for property 'artifactId': maven-tutorial
Define value for property 'version' 1.0-SNAPSHOT: : #엔터
Define value for property 'package' com.muckycode.app: : #엔터
Confirm properties configuration:
groupId: com.muckycode.app
artifactId: maven-tutorial
version: 1.0-SNAPSHOT
package: com.muckycode.app
 Y: : y #설정을 확인하고 맞으면 y를 쳐주자, 그리고 나면 아래와 같이 빌드가 만들어졌다는 문장들을 볼수있을거다.
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.1
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /home/user
[INFO] Parameter: package, Value: com.muckycode.app
[INFO] Parameter: groupId, Value: com.muckycode.app
[INFO] Parameter: artifactId, Value: maven-tutorial
[INFO] Parameter: packageName, Value: com.muckycode.app
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /home/user/maven-tutorial
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:26 min
[INFO] Finished at: 2017-06-16T10:58:19+09:00
[INFO] Final Memory: 18M/200M
[INFO] ------------------------------------------------------------------------

Maven에 의해 생성된 프로젝트 폴더로 가보자. basedir내부에 artifactID폴더에 있을거다. 폴더 내부 구성을 보게되면


user@user-desktop:~/maven-tutorial$ ls -LR
.:
pom.xml  src

./src:
main  test

./src/main:
java

./src/main/java:
com

./src/main/java/com:
muckycode

./src/main/java/com/muckycode:
app

./src/main/java/com/muckycode/app:
App.java

./src/test:
java

./src/test/java:
com

./src/test/java/com:
muckycode

./src/test/java/com/muckycode:
app

./src/test/java/com/muckycode/app:
AppTest.java

기본적으로 maven은 프로젝트 폴더안에 pom.xml, Project Object Model 파일인데, 프로젝트의 구성정보를 전달하는 파일이다.
그리고 src 폴더안에 main 폴더와 test 폴더를 생성하고, 각 폴더 내부에 java 폴더를 생성, java 폴더 내부는 groupID에 입력했던 패키지 형식 계층으로 폴더가 구성된다.
위는 maven-archetype-quickstart라는 archetype을 선택(기본값이다)했을때이고 다른 옵션을 정하면 그에 따라 만들어진다.
Maven에서 소개하는 기본 디렉토리 구조는 아래와 같다. 혹시 이 중에 필요하나 안만들어진게 있다면, 직접 폴더를 만들면 된다.


디렉토리설명
src/main/java자바 소스 파일
src/main/resources리소스 파일
src/main/filters리소스 필터 파일
src/main/webapp웹앱 소스 파일
src/test/java테스트 소스 파일
src/test/resources테스트 리소스 파일
src/test/filters테스트 리소스 필터 파일
src/it확장(Integration) 테스트(플러그인용)
src/assemblyAssembly descriptors
src/siteSite
LICENSE.txt프로젝트 라이센스
NOTICE.txtNotice 파일
README.txtreadMe 파일

위의 폴더 구조와 내부 파일 설명은 Maven 규칙이기도 하니 잘 지켜주자. 모든 자바 소스 파일들은 src/main/java 폴더에 존재해야하며, 모든 테스트 소스 파일들은 src/test/java 폴더에 존재해야하고, 같은 방식으로 리소스들은 resources 폴더에 저장된다. 또 필수사항은 아니지만, 소스파일들은 groupId와 같은 패키지 구조를 가지는게 좋고, 기본적으로 만들어지는 App.java, AppTest.java 파일은 Maven 작동 테스트를 위한것임을 알아두자.

기본적으로 Maven 설치는 최소한의 Maven 기능만 설치한다. 추가기능들은 모드 plug-in 방식으로 제공되며, plug-in의 이름만 주어지면, Maven이 알아서 다운받고 설치한다. 위 프로젝트 생성의 경우에는 Maven이 archetype이라는 플러그인을 다운받았고, archetype 플러그인이 의존하는 다른 플러그인까지 알아서 다 다운받았다. 이런 플러그인들은 로컬에 저장되며, 한번 다운받았으면 다시 다운받을 필요 없다.

자 그러면 다시 우리 프로젝트 폴더로 이동해서 mvn package 명령어를 실행해주자. 그럼 아까와 같이 플로그인 다운로드가 끝난이후 아래와 같은 결과를 보게 될것이다.
설명하자면, mvn package 명령에서 package 파라미터는 build 사이클의 한 단계(Phase)를 의미한다. 각 phase 들은 개별 플러그인이며, 이 플러그인들이 실행하는 하나의 행위들을 goal이라고 표현한다. 예를들어 package 단계의 어떤 goal을 실행하고 싶다면 mvn package:anygoal 이런식을 콜론을 이용해서 명령어를 만들어주면 된다. 각 단계는 실행되기위해 그 전단계들의 실행을 필요로 한다. 그렇기 때문에 이 경우에, 우리는 package 단계를 실행했고, 그 전 단계인 Validate, Compile, Test 단계가 다 실행되고 Package단계가 실행된다. 물론 Validate, Compile, Test 단계모두 각각 실행 할 수도 있다.

  • Validate - pom.xml 파일을 조회해 프로젝트 구성과, 필요 정보에 이상 없나 확인한다.
  • Compile - 소스파일을 컴파일한다
  • Test - 테스트 소스를 컴파일하고 테스트 프레임워크를 실행해 테스트한다
  • Package - pom.xml 파일에 설정된 포맷으로 프로젝트를 패키징한다. 여기서는 jar 포맷이다.


user@user-desktop:~/maven-tutorial$ mvn package
[INFO] Scanning for projects...

[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-tutorial 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------

################################################################################
# Validate 단계
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-tutorial ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/user/maven-tutorial/src/main/resources
[INFO] 

################################################################################
# 메인 소스 파일 변경을 감지하고 새로 컴파일한다 - Compile 단계
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-tutorial ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/user/maven-tutorial/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-tutorial ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/user/maven-tutorial/src/test/resources
[INFO] 

################################################################################
# 테스트 소스 파일 변경을 감지하고 새로 컴파일한다
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-tutorial ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/user/maven-tutorial/target/test-classes

################################################################################
# 테스트를 진행한다 - Test 단계
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-tutorial ---
[INFO] Surefire report directory: /home/user/maven-tutorial/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.muckycode.app.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

################################################################################
# 테스트 결과가 이상 없고, 마지막 단계인 package 단계를 실행하고 jar 파일을 생성한다.
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-tutorial ---
[INFO] Building jar: /home/user/maven-tutorial/target/maven-tutorial-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.654 s
[INFO] Finished at: 2017-06-16T13:13:28+09:00
[INFO] Final Memory: 17M/195M
[INFO] ------------------------------------------------------------------------

여기까지가 CLI로 Maven을 이용하는 법이다. 근데 아마 대부분의 개발자들은 본인 취향의 IDE를 이용해 할것이니, 조금만 더 힘을내서 Maven과 Eclipse 연동하는 법을 알아보도록 하자.

Eclipse IDE는 Maven을 자체 내장해서 나온다. 엥 그면 위에서 설치 괜히한거~는 아니고, Eclipse 내장 Maven말고 별도로 설치한 다른 버젼의 Maven과도 연동할 수 있으니 타버젼 Maven을 사용하고 싶으면 아래와 같은 방법으로 하면 된다.

우선 Help 메뉴에서 About Eclipse를 클릭하게되면 아래와 같은 창이 보일것이다.

About Eclipse 창

그림에서 빨간 사각형 안에 들어가있는 m2라고 적힌 버튼이 보이는가, 그게 바로 Eclipse Maven 플러그인이다. 클릭하면 자세한 정보도 볼 수 있다. 만약 안보인다면 Eclipse 플러그인 검색으로 설치해주자.

설치가 되있는것을 확인했으면 Window 메뉴에서 Preferences 창으로 들어간다음 Maven 검색후 Installations 를 클릭해준다.

Eclipse Preference Maven Installations 창

그면 위와같은 창을 보게 될텐데, 우선은 내장 Maven을 사용하고 있기에 Embedded에 체크되있다. 옆의 Add 버튼을 눌러 위에서 설치했던 최신버젼의 Maven을 추가해주자.

Eclipse Maven Runtime 추가창

올바른 디렉토리를 추가해주고 적당한 이름도 붙여주기만 하면 끝난다. 그럼 아까 그 창이 아래와 같이 변하게 되고, 체크박스만 바꿔주면 연동이 완료된다.

추가 완료 후 Maven Installations 창

새로운 Maven 프로젝트를 생성해보자. File - New-Maven Project를 선택하면 아까 CLI로 했던 과정을 쉽게 할 수 있다.

Eclipse New Maven Project 창 - 01

Create a simple project(skip archetype selection) 을 선택해주자, 아까처럼 복잡한 옵션을 건너뛰고 기본값으로 프로젝트를 생성시켜 준다. 다음을 누르면

Eclipse New Maven Project 창 - 02

CLI랑 별 다른건 없다. 프로젝트 설정을 완료해주고, 완료를 누르면 패키지 탐색기에 새로운 프로젝트가 추가된다.

Eclipse m2 플러그인은 Maven을 통해 위 과정을 완료하기때문에, CLI와 과정이나 결과로 별달리 차이가 없다.

이미 생성된 프로젝트를 가져오기 위해서는 File - Import 에서 Existing Maven Project 선택 후 프로젝트 디렉토리 위치를 입력하면 된다. pom.xml 파일을 통해 프로젝트를 구성하기 때문에 pom.xml 파일에 입력된 설정, 의존성(Dependency)를 재구성한다.

2017년 6월 15일 목요일

[Ubuntu] 우분투 데스크탑 아이콘 만들기

우분투 데스크탑 환경인 UNITY에서 프로그램을 실행하기 위해서는, 설치한 어플리케이션을 .desktop 파일인 desktop entry를 데스크탑 메뉴에 추가해줘야 한다. 참고로 이는 freedesktop.org의 기준을 따르는 모든 데스크탑 환경에서 동일하다. 데스크탑 환경은 .desktop 파일에서 정보를 읽어, 아이콘을 만들어준다.

아래는 간략한 desktop 파일의 양식과 설명이다


[Desktop Entry] 
# 모든 desktop 파일의 첫줄이다. 데스크탑 환경이 파일을 바르게 인식하려면 필수적으로 첫줄에 들어가야 한다.
Type = 
# 데스크탑 환경에 이 파일이 어떤것과 관련되었는지를 알려준다. 값으로는 Application, Link, Directory가 있다.
Version =
# desktop 파일의 버젼이다. 현재로써는 1.1이 최신
Name = 
# 데스크탑 메뉴와 런쳐에 보일 어플리케이션 이름
GenericName =
# 총칭 Chrome 의 경우에는 Web-Broswer 이런식
Encoding =
# desktop 파일의 인코딩
Comment = 
# 어플리케이션에대한 설명, tooltip 형식으로 보인다
Exec = 
# 쉘에서 어플리케이션을 실행하는 명령어
Icon = 
# 아이콘 이미지
Terminal = 
# true, false 값으로 어플리케이션이 터미널에서 실행되어야하는지를 정한다.

나는 xampp를 설치하고, 쉘에서 실행할려니 불편해서 만들려 한다.


[Desktop Entry]
Type = Application
Encoding = UTF-8
Name = LAMPP Manager
Comment = LAMPP Control Panel
Exec= gksu /opt/lampp/manager-linux-x64.run
Icon= /opt/lampp/favicon.ico
Terminal = false

이런 LamppManager.desktop파일을 만들어 usr/share/applications 폴더에 놔주면 끝

2017년 1월 30일 월요일

[JavaScript] 자바스크립트 이벤트 핸들링(Event Handling)

Events란 사용자, 또는 브라우저에 의해 실행되는 행위들을 말한다. 이러한 event들에는 click, load, mouseover, focus 등이 있다. Event가 있으면 이들을 사용하는 것도 있는데, event에 반응하는 함수(function)들을 event handler, 또는 event listener라 부른다. event listener 들의 이름은 간단하다. Onclick, onload, onmouseover, onfocus처럼 원하는 event에 on을 붙이면 된다.
이러한 Event Handler들을 등록하는데 3가지 방법이 있다

HTML Event Handler



<div clicked="" onclick="(function(){alert(onmouseover=alert('mouseover')">
</div>

원하는 event 프로퍼티에 javascript statement들을 적어주면 된다. Javascript statement가 들어가기 때문에, self executing function 또는 함수 호출 또한 적을 수 있다. 주의할 점은, 자바스크립트 코드들이 HTML의 프로퍼티 값으로 들어가게되어, HTML 문법에 포함되는 문자들을 사용해서는 안된다. 예를들어, <, >, “, 등을 escape character 가 아닌 방식으로 사용하게 되면 페이지에 에러가 발생할 수도 있다. 그러니 " < > 등의 특수문자 코드를 이용하여야 한다.

이런 방식으로 등록된 event handler들은 attribute란에 있는 자바스크립트 구문들로 function을 생성하는것과 같은 효과를 내게 된다. 관련 event 객체에 접근할 수 있는 event라는 로컬 변수를 가지게 되며, event 객체를 새로 선언하거나 argument 리스트에서 객체를 찾아오지 않고도 event 객체를 사용할 수 있게 해준다.


<div onclick="”(function(){alert(event.type);})()”">
</div>

또한 이렇게 생성된 함수 scope내의 this 값은 event handler가 등록된 html element가 되며, document 객체와 this 객체 내부 변수들을 로컬 변수처럼 사용할 수 있다. 이는 html event handler 가 지금은 deprecated 된 with 문을 이용해 함수를 구성하기 때문이다.


<div onclick="”(function(){alert(this.type);})()”">
</div>
//위의 코드는 아래와 같다
 
function(){
with(document){
with(this){
alert(this.type):
}
}
}

그러므로 this.type을 그냥 type으로 교체해도 함수는 잘 작동하게된다. 또 이로인해서 event handler 내에서 이벤트가 발생한 html 엘리멘트의 프로퍼티에 더 쉽게 접근할 수 있다.

HTML event handler의 단점을 말하자면, 첫번째로 시점 문제를 들 수 있다. 예전에 script defer, async 태그 글에서 말했던것 처럼, script가 로딩과 html 페이지 로딩, 렌더링은 모두 같은 시점에서 완료되지 않는다. 만약 우리가 html event handler에서 별도의 스크립트 파일 내의 함수를 호출하게 될때. Script 가 더 늦게 로딩된다면 웹브라우져는 그 함수를 찾지 못하고 에러를 발생시키게 될것이다. 그렇기 때문에 대부분의 html event handler들은 try catch문을 필수적으로 사용하게 된다.

또다른 단점으로는 script와 html간의 의존성이다. Html안에 script가 들어간 형식이기 때문에 script의 수정은 바로 html의 수정으로 이어지고, 역으로 html의 수정은 script의 수정으로 이어지게 된다. 이때문에 코드가 조금만 복잡해져도 일이 2배가 되니, 가능하면 html event handler의 사용을 피하도록 하자.


DOM Level 0 Event handler


HTML Element 객체를 호출해 객체의 프로퍼티에 어싸인하는 방식이다.

var button = document.getElementById(“login”);
button.onclick = function(){
alert(this.id); // “login”
process_login();
}

window, document 객체를 포함한 모든 Element 객체는 이벤트 핸들러 프로퍼티를 가지고 있다. 단 모든 이벤트 핸들러 프로퍼티는 모두 소문자로 되어있으며(onclick, onfocus, etc.), 이 프로퍼티에 함수를 어싸인하여 이벤트를 핸들할 수 있다.

위의 예제에서는 login이라는 id를 가진 html element 객체가 호출되었고, 해당 객체의 onclick 프로퍼티에 함수를 어싸인하였다. Event handler 가 스크립트 상에서 어싸인되기때문에, 해당 코드가 실행될때까지는 이벤트가 발생해도 핸들링 되지 않는다. 또한, 어싸인된 이벤트핸들 함수는 이벤트가 발생한 HTML Element 객체의 프로퍼티이기 때문에 그 함수내에서 this 값은 이벤트가 발생한 Element 객체와 같다.

이렇게 어싸인된 이벤트 핸들러를 제거하려면 해당 프로퍼티에 null 값을 어싸인해주면 된다

button.onclick = null;

이 이벤트핸들러는 DOM Level 0 에서 소개되었기 때문에 그냥 DOM Level 0 Event handler로 불린다.

DOM Level 2 Event Handler


DOM Level 0 에서 객체의 프로퍼티를 이용해 이벤트 핸들러를 어싸인한것과 달리, DOM Level 2 에서는 2개의 함수를 이용해 이벤트핸들러를 추가, 제거하는 방법을 소개했다. 모든 DOM node들에는 addEventListener() 함수와 removeEventListener()함수가 존재하며 이 함수들은 핸들할 이벤트 이름, 핸들 함수, 그리고 Event Capture 단계에서 이벤트를 핸들할지(true), Bubble단계에서 이벤트를 핸들할지(false) 여부에 대한 Boolean 값을 포함해 총 3개의 argument들을 받는다.

예를들어 bubble 단계에서 click 이벤트를 핸들할 함수를 어싸인하는것은 아래아 같다


var button = document.getElementID(“button”);
var showAlert =  function(){
alert(“you clicked” + this.id);
}
button.addEventListener(“click”,showAlert,false);

DOM Level 0 과 같이 this 값은 해당 element 객체와 같다.

DOM Level 2 방식의 가장 큰 장점은 1개의 이벤트에 여러개의 이벤트 핸들러를 어싸인 가능하다는 것이다.


var button = document.getElementID(“button”);
var showAlert =  function(){
alert(“you clicked” + this.id);
}
button.addEventListener(“click”,showAlert,false);
button.addEventListener(“click”,function(){alert(“second message”);},false);

위의 경우에 이벤트 핸들러는 추가된 순서대로 실행되게 된다.

DOM Level 2 방식으로 추가된 핸들러들은 DOM Level 2 방식으로만 제거될 수 있다. 즉 addEventListner 함수로 추가한 이벤트 핸들러가 있다면 같은 argument로 호출된 removeEventHandler만이 제거할 수 있다는 뜻이다. 그렇기 때문에 만약 익명함수의 이벤트 핸들러를 추가했다면, 그 이벤트 핸들러의 제거는 불가능 하다는 뜻이기도 하다.


var button = document.getElementID(“button”);
var showAlert =  function(){
alert(“you clicked” + this.id);
}
button.addEventListener(“click”,showAlert,false);
button.addEventListener(“click”,function(){alert(“second message”);},false);
button.removeEventListener(“click”,showAlert,false);
button.removeEventListener(“click”,function(){alert(“second message”);},false);

위의 예제에서 첫번재 이벤트 핸들러는 제거되었지만 2번째 이벤트 핸들러는 제거되지 않았다. 2번째 이벤트 핸들러 제거를 위해 완벽히 일치하는 argument를 넘긴것 같지만, 지난 함수 글에서 말했듯 함수는 객체이고, 새로운 객체인 anonymous 함수를 생성하였기 때문에 2번째 핸들러는 제거되지 않는다.

2016년 12월 10일 토요일

[Java] 자바 시작하기(개발 환경 구성)

자바(Java)프로그래밍을 시작하기위해 가장 선행되어야 할 것은, JRE(Java Runtime Environment, 자바 실행 환경) 설치, 즉 JVM(Java Virtual Machine, 자바 가상 머신)라 불리는 가상머신과 각종 Java API들을 포함하고 있는 JDK(Java Development Kit, 자바 개발 키트)의 설치이다. Java API는 각종 기능의 자바 클래스들이 포함된 자바 라이브러리이고 JVM은 컴파일된 자바 클래스파일들을 실행하는 가상 머신이다. 단순한 자바  프로그램 이용자라면 JVM만이 포함된 JRE를 설치하면 되겠지만 자바 개발자들은 이 2개가 모두 필요하기 때문에 Oracle에서는 JDK에 이 2가지를 포함하여 쉽게 설치할 수 있도록 하고 있다.

JDK를 다운받을려면 오라클 JDK 다운로드 페이지로 이동하자. 링크를 클릭하면 아래와 같은 페이지를 보게될것이다.

Oracle Java SE 다운로드 페이지

좌측 상단에는 각종 Java 제품들의 종류별로 카테고리가 나눠져 있고, 중앙 상단에는 JDK 설치와 NetBeans와 JDK를 함께 설치할 것인지 선택 옵션이 있다. 그리고 중앙 하단 우측에는 JDK, Server JRE, JRE 3개 선택 페이지가 있다. 참고로 형광펜으로 색칠된것을 보면 현재 Java SE는 8u112버젼이 최신 버젼인것을 알 수 있다. Java 8의 112번째 Update 라는 뜻이다.

참고로 JAVA SE는 Standard Edition, 데스크톱 어플리케이션과 간단한 서버 어플리케이션 개발 사용되며 EE는 Enterprise Edition, 복잡한 서버 어플리케이션 개발에, ME는 Micro Edition, 스마트폰과 기타 장치들에 사용된다. NetBeans는 Oracle에서 제공하는 IDE이다.

우리는 JDK가 필요하니 중앙 상단의 JDK설치만 설치를 클릭하자(왼쪽 옵션이다).
클릭 후 새 페이지로 이동하면 OS 별 JDK 리스트를 볼 수 있을텐데 본인 OS에 맞는 JDK를 설치하자. 나는 Ubuntu 16.04 64bit 버젼을 사용하므로 Linux x64(tar.gz)를 다운받았다. 윈도우 사용자들은 Window x32, x64를 윈도우 버젼에 맞게 설치하면 된다. 윈도우 사용자들은 설치파일을 단순히 실행하면 설치가 가능하고, linux 사용자들은 아래와 같이 설치하면 된다.


#파일 다운로드가 완료된 디렉토리로 이동 후 ~
#파일 압축해제
user@user-desktop:~/Downloads$ tar -xvf jdk-8u112-linux-x64.tar.gz
#파일 이름변경
user@user-desktop:~/Downloads$ mv jdk1.8.0_112 jdk1.8
#opt 폴더 내 java 디렉토리 생성
user@user-desktop:~/Downloads$ sudo mkdir /opt/java
#jdk1.8 폴더를 /opt/java 로 이동
user@user-desktop:~/Downloads$ sudo mv jdk1.8 /opt/java

이렇게 하면 다운받은 JDK가 /opt/java 폴더 내로 이동된다. 이후에 리눅스 사용자들은 jdk1.8/bin 디렉토리를 executable path에 추가해 주어야 한다. 윈도우 사용자들도 설치된 jdk를 환경변수에 등록해주어야 한다.


user@user-desktop:~$ sudo vi .profile
#.profile 파일을 열어 export PATH=/opt/java/jdk1.8/bin:$PATH 구문을 추가해주자

그리고 로그아웃 후 다시 로그인 하면 아래와 같이 자바가 설치되었음을 알 수 있을것이다.


user@user-desktop:~$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)