자바의 패키지(package)는 클래스(interface, enum..)의 묶음으로서 하나의 디렉토리(폴더)이다. 패키지의 이름과 같은 디렉토리 내에 클래스 파일들을 포함하며 하위 패키지도 포함하는 중첩된 구조도 가능하다. ( C/C++에 비해서 무척 단순한 구조를 가지고 있다.)


[그림 1] 자바의 패키지 구조. 패키지는 디렉토리임.


퍼블릭 클래스(퍼블릭 인터페이스, 퍼블릭 이넘..)가 물리적으로 하나의 파일인 것과 유사하게 패키지는 물리적으로 하나의 디렉토리이다. 즉, 같은 폴더 내의 이러한 파일들이 패키지를 구성한다. 예를 들어서 java.lang.System 클래스는 java패키지의 하위 패키지인 lang에 속한다. 따라서 물리적으로 java디렉토리 밑의 lang디렉토리 밑의 System.class 파일이다.


 예를 들어서 netbean에서 tut01이라는 프로젝트를 생성하면 처음에 다음과 같으 구조를 가진다. tut01이라는 프로젝트 폴더 밑에 src/tut01 폴더가 tut01 패키지가 된다. 그리고 그 안에 Tut01.java파일이 자동으로 생성되며 맨 첫 줄에 패지지가 명시되어 있다.


[그림 2] tut01 프로젝트 생성


클래스 파일의 (주석과 공백을 제외한) 맨 처음에는 소속 패키지를 선언하는 단일문이 위치해야 한다. [그림 2]에서도 맨 첫 줄에 ‘package tut01;’이라고 소속 패키지가 명시되어 있다.


 하나의 프로젝트는 일반적으로 하나 이상의 패키지를 포함한다. <프로젝트 디렉토리>/src 디렉토리 안에 패키지를 생성할 수도 있고 특정 패키지 안에도 하위 패키지를 생성할 수 있다.


[그림 3] 새로운 패지키들의 생성


해당 폴더에 들어가서 확인해 보면 새로운 패키지를 생성하면 같은 이름의 폴더가 생성된 것을 알 수 있다.


[그림 4] 생성된 폴더


위 그림에는 안 보이지만 tut01 폴더 하위에 sub01 패키지(폴더)가 생성되어 있고 src 밑에는 tut02, tut03 이라는 폴더가 생성된 것을 알 수 있다.


 그리고 자바 프로젝트를 빌드하면 <프로젝트디렉토리>/dist 디렉토리 밑에 jar 파일이 생성되는데 이것은 프로젝트 내의 모든 컴파일된 패키지를 포함한 압축파일이다. 예를 들어서 위의 프로젝트를 빌드하면 tut01/dist/tut01.jar 파일이 생성된다. 이 파일을 열어보면 이 프로젝트에 포함된 패키지들이 생성되어 있음을 알 수 있다.


[그림 5] winrar로 본 tut01.jar의 내용. tut01, tut02, tut03 패키지(디렉토리)가 보인다.


이것을 실행하려면 명령창에서 다음과 같이 하면 된다.


java -jar tut01.jar


[그림 6] 일반적인 자바 프로젝트(jar파일) 구조


 이와 같이 프로젝트는 패키지의 모음이며 패키지는 클래스 파일들의 묶음이라는 자바 디렉토리의 구조를 이해해야 한다.



Posted by 살레시오
,

 자바 인터페이스(interface)는 추상 클래스와 비슷한 점이 있지만 한 단계 더 추상화된 클래스이다. 기본적으로 다음과 같이 정의한다.


interface 인터페이스명 {
   public static final 자료형 변수명 = 변수값;
   public abstract 반환자료형 함수명(입력인자들);
}


인터페이스의 멤버 변수는 public static final 로만 지정 가능하고 이것은 생략할 수 있다. 인터페이스 변수는 final 이므로 반드시 변수값을 선언부에 지정해 주어야한다.  멤버는 public abstract 가 기본형으로서 이것도 생략할 수 있다. 예를 들면 다음과 같다.


interface IA {
   int ia = 11; // 앞에 public static final 이 생략됨
   void fun();  // 앞에 public abstract 가 생략됨
}


인터페이스도 추상 클래스와 마찬가지로 직접 객체를 생성할 수 없으며 이것을 구현하는 클래스는 객체화 할 수 있다.


class CA implements IA {
   public void fun() {
       int ib = ia + 11; // ia는 인터페이스에서 정의된 정적 변수이다.
       System.out.println(“fun() redefined.”);
   }
}


추상클래스와 다르게 인터페이스는 이를 구체화하기 위해 implements 라는 키워드를 사용하고 그 뒤에 구현할 인터페이스 명을 써야한다. IA를 구체화하기 위해서는 반드시 추상 메소드인 fun()의 본체를 위와 같이 정의하여야 한다. 그리고 fun()의 접근 지정자는 반드시 public이어야 한다. 그 이유는 인터페이스에서 (생략되었다 할 지라도) public abstract 으로 정의되었기 때문이다.


 실행 가능한 예를 들면 다음과 같다.


package tut03;

public class Tut03 {
   public static void main(String[] args) {
       Violin v1 = new Violin();
       v1.ready();
       v1.play();

       Guitar g1 = new Guitar();
       g1.ready();
       g1.play();
   }
}

interface Playable {
   String player = "살레시오";
   void ready();
   void play();   
}

class Violin implements Playable {
   public void ready() {
       System.out.println(player+"의 바이올린이 준비되었다.");
   }
   public void play() {
       System.out.println("낑~깡~낑~깡~");
   }
}

class Guitar implements Playable {
   public void ready() {
       System.out.println(player+"의 기타가 준비되었다.");
   }
   public void play() {
       System.out.println("디리링~디리링~");
   }    
}


이 예에서는 Playable 이라는 인터페이스를 구현한 Violin과 Guitar 클래스를 작성하였다. 인터페이스의 이름은 관례적으로 ~able 로 끝나는 것들이 많다.


 이와 같이 인터페이스는 구현하고자하는 여러 클래스의 공통적인 부분(정적 변수와 public 함수)만 기술해 놓은 기초 설계도와 같고 인터페이스를 구현하는 클래스에서 추상 메소드의 몸체를 모두 정의하도록 강요한다. 만약 인터페이스 구현하는 어떤 클래스가 모든 추상 메소드를 구현하지 않는다면 그 클래스는 추상 클래스가 되어야 한다는 점도 알아두어야 한다. JAVA8에서는 인터페이스에 대한 규약이 좀 더 확장되었는데 이것은 다른 포스트에서 다루도록 하겠다.



Posted by 살레시오
,

 넘파이(numpy)를 사용하기 위해서는 다음과 같이 import 해야 한다. winpython, python(x,y)에는 기본적으로 포함되어 있으므로 바로 사용할 수 있다. import 명령을 이용하면 되는데 다음과 같이 몇 가지 방법이 있다.


>>> import numpy # 넘파이의 모든 객체를 numpy.obj 형식으로 불러 사용할 수 있다.
>>> import numpy as np  # 넘파이의 모든 객체를 np.obj 형식으로 불러 사용할 수 있다.
>>> from numpy import * # 넘파이의 모든 객체를 내장 함수 (객체) 처럼 사용 가능.

 

넘파이는 ndarray (n-dimensional array 의 약어, 이후 배열) 라는 객체를 사용하는데 이는 리스트와 유사하지만 다차원 데이터의 연산에 좀 더 효율적이라고 한다. 리스트는 모든 형식의 객체를 저장할 수 있지만 배열은 한 행의 요소는 모두 같은 자료형어야 한다.

배열 생성

 배열을 입력하는 가장 기본적인 함수는 array() 이다. 첫 번째 인자로 리스트를 받는데 이것으로 array객체를 생성한다.

>>> np.array( [1, 2, 3] ) #1차 배열 (벡터) 생성
>>> np.array( [ [1, 2, 3], [4, 5, 6] ) # 2x3 크기의 2차원 배열 (행렬) 생성

일반적으로 3차원, 4차원, ... , n차원 배열도 중첩리스트를 이용하여 유사하게 생성할 수 잇다.

 파이썬의 내장 함수인 range()와 유사하게 배열 객체를 반환해주는 arange() 함수가 있다.

>>> np.arange(10) # 1차원 배얼 [0,1,2, ... ,9] 생성


그리고 시작점과 끝점을 균일 간격으로 나눈 점들을 생성해주는 linspace()함수도 있다.


>>> c = np.linspace(0, 1, 6)   # start, end, num-points
>>> c
    array([ 0. , 0.2, 0.4, 0.6, 0.8, 1. ])

>>> d = np.linspace(0, 1, 5, endpoint=False)
>>> d
    array([ 0. , 0.2, 0.4, 0.6, 0.8])

생성된 배열은 reshape() 함수를 이용하여 행수와 열수를 조절할 수 있다.

>>> a = np.arange(10) # 1차원 배열 [0,1,2, ... ,9] 생성
>>> a = a.reshape(2,5) # 같은 요소를 가지고 2x5 배열로 변형


특수 행렬 생성

 넘파이에는 특수 행렬을 생성하기 위한 함수들이 있다. zeros(), ones() 라는 함수들은 각각 0과 1로 채원진 배열을 생성하는데 차수를 정수 혹은 튜플로 받는다. 예를 들어서 0으로 채워진 5x5 배열을 만들고 싶다면 다음과 같이 한다.

>>> b1 = np.ones( 10 ) # 1로 채원진 10 크기의 (1차원) 배열 생성
>>> b2 = np.zeros( (5,5) ) # 0으로 채원진 5x5 크기의 배열 생성


대각행렬을 생성하기 위한 eye() 함수와 diag() 함수도 있다. eye() 함수는 항등행렬을 생성하고 diag()는 주어진 정방행렬에서 대각요소만 뽑아내서 벡터를 만들거나 반대로 벡터요소를 대각요소로 하는 정방행렬을 만들어 준다..

  

         정의 : eye(N, M=, k=, dtype=), M은 열 수, k는 대각 위치(대각일 때가 0), dtype은 데이터형


>>> np.eye(2, dtype=int)
    array([[1, 0],
           [0, 1]])

>>> np.eye(3, k=1)
    array([[ 0.,  1.,  0.],
           [ 0.,  0.,  1.],
           [ 0.,  0.,  0.]])


         정의:  diag(v, k=0), v는 array_like, k는 대각 위치


>>> x = np.arange(9).reshape((3,3))
>>> x
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
>>> np.diag(x)
    array([0, 4, 8])
>>> np.diag(x, k=1)
    array([1, 5])
>>> np.diag(x, k=-1)
    array([3, 7])
>>> np.diag(np.diag(x))
    array([[0, 0, 0],
           [0, 4, 0],
           [0, 0, 8]])

 

이에 반해서 empty() 라는 함수는 크기만 지정해 두고 각각의 요소는 초기화 시키지 않는다. 따라서 이 함수로 생성된 배열의 요소는 가비지값이 채워져 있다.


>>> c = np.empty( (2,2) ) # 가비지 값으로 채원진 2x2 크기의 배열 생성



Posted by 살레시오
,

 자바도 클래스의 멤버 각각에 외부에서 접근할 수 있는 범위를 지정하는 접근 지정자(access modifier)를 둘 수 있다. 다음과 같은 네 가지가 있다.



접근 지정자

접근 범위

동일
클래스

동일
패키지

다른
패키지의
자식
클래스

다른
패키지

public

접근 제한 업음

O

O

O

O

protected

동일 패키지와 상속 받은 클래스 내부

O

O

O


default

동일 패지키 내에서만

O

O



private

동일 클래스 내에서만

O





public

 공개 정도가 가장 높고 어디에서든 자유롭게 접근할 수 있다.

protected

 같은 패키지 내에서 접근이 가능하고 다른 패키지에서도 상속을 받은 클래스 내부에서는 사용 가능하다. public과 다른 점은 다른 패키지의 자식 클래스 외부에서는 접근할 수 없다는 것이다.

default (package private)

 같은 패키지 내에서만 접근이 가능하다. 아무런 접근 지정자도 없을 경우 이 옵션이 자동으로 적용된다.

private

 동일 클래스 내에서만 접근이 가능한 가장 낮은 단계의 자유도를 갖는다.


다음과 같이 tut02 패키지의 CA클래스와 이를 상속받은 CB클래스가 있다고 하자.


package tut02;
public class CA {
   public int ia;
   protected int ib;
   int ic;
   private int id;
   
   public static int ie;
   protected static  int ig;
   static int ih;
   private static int ii;
}


같은 패키지(즉 tut02 패키지) 내에서는 클래스 외부에서 변수 ia, ib, ic를 자유롭게 접근할 수 있고 id는 외부에서는 접근이 안된다. 이 클래스가 같은 패키지 내에서는 public, protected, default 가 같은 효과를 갖는다. 이것을 상속받은 자식 클래스에서도 ia,ib,ic는 접근 가능하다.


 만약 외부에서 tut02패키지의 CA 클래스를 불러서 사용하는 경우를 보자.


package tut03;
import tut02.CA;

public class Tut03 {
   public static void main(String[] args) {
       CA a = new CA();// ia만 접근 가능
       CC c = new CC();// ia만
   }   
}

class CC extends CA {
   //ia, ib, ie, ig 접근 가능
}


객체 a와 c는 외부에서 ia 멤버만 접근할 수 있다. 즉 클래스 외부에서 접근할 수 있는 멤버는 public으로 지정된 것만이다. protected로 선언된 멤버들은 CA를 상속하는 CC 내부에서만 사용 가능하다. 즉, protected로 선언된 멤버는 다른 패키지에서 이것을 상속받은 자식 클래스의 private 멤버가 되는 것이다. 클래스 CC내부에서도 CA의 ic, id는 접근할 수 없는데 default, private 멤버는 다른 패키지에서는 접근이 안 되기 때문이다.




Posted by 살레시오
,

 추상 클래스(abstract class)란 하나 이상의 추상 메소드(abstract method)를 포함하는 클래스이다. 추상 메소드는 선언만 있고 본체는 없는 함수이며 선언부에 ‘abstract’ 라는 키워드를 붙인다. 추상 메소드가 포함되었다면 클래스도 추상 클래스이므로 클래스명 앞에도 ‘abstract’키워드를 붙여야 한다.


abstract class Animal {
   public String sName; //일반 멤버 변수
   ….
   public void move() { …} // 일반 메소드
   abstract void howl(); //추상 메소드
   …
}


추상 클래스는 추상 메서드를 포함하고 객체화 할 수 없다는 점만 제외하고 일반 클래스와 다르지 않으며 생성자, 멤버변수와 일반 메서드도 가질 수 있다. 추상 클래스 자체로는 클래스로의 역할을 하지 못하며 객체를 생성할 수 없지만 새로운 클래스를 작성하는데 있어서 부모 클래스로서 중요한 역할을 갖는다. 위의 예에서 Animal 클래스는 직접 객체를 생성하지 못하고 이를 상속받는 자식 클래스에서는 추상 메소드의 구체적인 본체를 가질 수 있다.


package tut02;

abstract class Animal {
   public String sName;
   public void move() {
       System.out.println("어슬렁 어슬렁");
   }
   abstract void howl();
}

class Dog extends Animal {
   public void move() {
       System.out.println("팔짝 팔짝");
   }

   void howl() {
           System.out.println("멍멍");
   }
}

class Cat extends Animal {
   void howl() {
           System.out.println("냐옹");
   }
}

public class Tut02 {

   public static void main(String[] args) {
       Dog happy = new Dog();
       Cat julia = new Cat();
       happy.move(); // 오버라이드된 멤버함수 호출
       happy.howl(); // 구현된 멤버함수 호출
       jular.move(); // 일반 멤버함수 호출
       julia.howl(); // 구현된 멤버함수 호출
   }
}
실행 결과
팔짝 팔짝
멍멍

어슬렁 어슬렁

냐옹


추상 메소드의 접근 지정자로 private는 사용할 수 없는데 이는 자식 클래스에서 받아서 구현되어야 하므로 당연하다. 다른 접근 지정자(public, protected)는 사용할 수 있고 생략되면 default (즉, 같은 패키지 안에서만 접근 가능)인 것은 일반 클래스와 동일하다.


 위의 예에서 처럼 추상 클래스는 다른 클래스들에게서 공통으로 가져야하는 메소드들의 원형을 정의하고 그것을 상속받아서 구현토록 하는데 사용된다. 메소드 오버라이드(override)와 유사해서 혼동하기 쉬우나 오버라이드는 안해도 상관없지만 추상 메소드는 자식 클래스에게 그 구현을 강요하는 기능을 한다. 위 예에서도 Dog 클래스는 move()메소드를 오버라이드 했지만 Cat클래스는 그러지 않았다. 하지만 howl()메소드는 반드시 구현해야 한다. 그리고 만약 어떤 추상클래스를 상속 받은 자식 클래스에서 추상 메소드를 구현하지 않았다면 자식 클래스도 추상 클래스가 되어야 한다는 점도 알아 두자.



Posted by 살레시오
,

 오픈소스 프로그래밍 언어 중에 줄리아(Julia)라는 과학 계산용 언어가 있는데 아직 초기 버전이고 인터프리터 언어임에도 불구하고 C 컴파일된 것과 필적하는 성능을 보여주고 있어서 요즘 주목을 받고 있다. (요새는 JIT컴파일링은 아예 기본이 된 느낌이다.) 튜토리얼 동영상을 잠깐 봤는데 첫 인상은 파이썬과 matlab을 합쳐놓은 듯한 문법을 가지고 있다. (과학 계산용 언어에서 matlab의 영향은 무시할 수 없나 보다.) 아래 그림은 줄리아 홈메이지에서 캡쳐한 것이다.



위 표에 기록된 숫자들은 C프로그램의 성능을 1로 보았을 때 해당 언언의 성능 수치들이다 (낮은 수록 더 높은 성능임) 다음과 같은 몇 가지를 확인해 볼 수 있다.


  • octave의 성능은 matlab에 훨씬 못 미친다. octave는 그냥 matlab문법 연습용으로나 사용하고 실제 프로젝트에서 사용은 신중히 고려해보야야 할 것 같다.

  • 그리고 자바가 성능이 의외로 높다는 점이다. 여기에서는 JDK7으로 테스트했는데 JDK8 이상으로 하면 더 올라갈 것 같다.


파이썬과 matlab을 알고 있다면 줄리아를 익히는데 시간이 많이 걸릴 것 같지 않다. 그런데 이 그림을 보고 새삼 느끼는 점은 ‘자바를 더 공부해야겠다’ 였다. 줄리아도 판올림을 하고 정식 버전이 가까이 되면 훨씬 더 발전할 것 같긴 하다..




'프로그래밍언어.Lib' 카테고리의 다른 글

스크래치로 AI를 구현할 수 있다고?  (0) 2020.06.10
Posted by 살레시오
,

 이전 포스트에서 설명한 포장형(wrapper class)의 생성자를 이용하면 문자열을 기본형 값으로 바꿀 수 있다.


[표 1] 포장형의 기본형 값을 반환하는 객체 메쏘드

메소드명

기능

byteValue()

byte값을 반환한다.

shortValue()

short값을 반환한다.

intValue()

int값을 반환한다.

longValue()

long값을 반환한다.

floatValue()

float값을 반환한다.

doubleValue()

double값을 반환한다.


예를 들어서 다음과 같이 Integer 형 객체에서 다양한 기본형 값을 얻을 수 있다.


package tut02;
public class Tut02 {
   public static void main(String[] args) {
       int ia = new Integer("1234567").intValue();
       float fa = new Integer("1234567").floatValue();
       short sa = new Integer("1234567").shortValue(); //(*)

       System.out.println(ia);
       System.out.println(fa);
       System.out.println(sa);
   }
}
실행 결과
1234567
1234567.0
-10617


위의 (*)에서와 같이 손실 변환(lossy conversion)의 경우에도 별다른 경고나 오류를 발생하지 않는다. 따라서 같은 형의 데이터의 변환에만 쓰는 것이 바람직하다.


 포장형으로 부터 기본형 값을 얻는 메소드로 parse 로 시작하는 정적 메소드들이 있다. 이 메소드를 이용하면 정수형을 반환하는 메소드는 기수를 지정해 줄 수도 있다.


[표 2] 포장형의 기본형 값을 반환하는 메쏘드

메소드명

기능

Byte.parseByte(String)

Byte.parseByte(String, radix)

문자열을 byte값으로 변환한다.

기수 radix인 문자열을 byte값으로 변환한다.

Short.parseShort(String)

Short.parseShort(String, radix)

문자열을 short값으로 변환한다.

기수 radix인 문자열을 short값으로 변환한다.

Integer.parseInt(String)

Integer.parseInt(String, radix)

문자열을 int값으로 변환한다.

기수 radix인 문자열을 int값으로 변환한다.

Long.parseLong(String)

Long.parseLong(String, radix)

문자열을 long값으로 변환한다.

기수 radix인 문자열을 long값으로 변환한다.

Float.parseFloat(String)

문자열을 float값으로 변환한다.

Double.parseDouble(String)

문자열을 double값으로 변환한다.


실제 프로그램에서는 주로 [표 2]의 정적 메소드를 자주 사용하게 된다.


package tut02;
public class Tut02 {
   public static void main(String[] args) {
       int ia = Integer.parseInt("1234567");
       int ib = Integer.parseInt("11110010",2); //이진수
       int ic = Integer.parseInt("1ab3f",16); //십육진수

       System.out.println(ia);
       System.out.println(ib);
       System.out.println(ic);
   }
}
실행 결과
1234567
242
109375


 포장형 객체를 반환하는 valueOf() 이라는 정적 메소드도 있다.


[표 3] 문자열로 부터 포장형 객체를 반환하는 메쏘드

메소드명

기능

Byte.valueOf(String)

Byte.valueOf(String,radix)

Byte.valueOf(byte)

문자열을 Byte 객체로 변환

기수 radix인 문자열을 Byte 객체로 변환한다.

byte값을 Byte 객체로 박싱

Short.valueOf(String)

Short.valueOf(String,radix)

Short.valueOf(short)

문자열을 Short 객체로 변환

기수 radix인 문자열을 Short 객체로 변환한다.

short값을 Short 객체로 박싱

Integer.valueOf(String)

Integer.valueOf(String,radix)

Integer.valueOf(int)

문자열을 Integer 객체로 변환

기수 radix인 문자열을 Interger 객체로 변환한다.

int값을 Interger 객체로 박싱

Long.valueOf(String)

Long.valueOf(String,radix)

Long.valueOf(long)

문자열을 Long 객체로 변환

기수 radix인 문자열을 Long 객체로 변환한다.

long값을 Long 객체로 박싱

Float.valueOf(String)

Float.valueOf(float)

문자열을 Float 객체로 변환한다.

float값을 FLoat 객체로 박싱

Double.valueOf(String)

Double.valueOf(float)

문자열을 Double 객체로 변환한다.

float값을 Double 객체로 박싱


예를 들어서


int ia = Integer.valueOf("1234567");


이렇게 하면 자동 언박싱이 일어나서 변수 ia에 1234567이란 값이 저장된다. 하지만 parseInt()함수보다는 당연히 성능이 떨어진다.




Posted by 살레시오
,

 자바에는 int, double과 같은 기본형 자료형(primitive type)의 포장 클래스(wrapper class)가 있어서 기본형을 객체로 다루어야 할 경우에 사용할 수 있다. 다음 표에서와 같이 포장 클래스명은 기본형의 첫 문자를 대문자로 바꾸면 된다.( char형과 int형만 이름이 다르다.)


[표 1] 포장 클래스

기본형

포장 클래스

생성 예

boolean

Boolean

Boolean bA = new Boolean(true);

Boolean bB = new Boolean(“false”);

char

Character

Character cA = new Character(‘a’);

byte

Byte

Byte byA = new Byte(10);

Byte byB = new Byte(“127”);

short

Short

Short sA = new Short(1234);

Short sB = new Short(“1234”);

int

Integer

Integer iA = new Integer(1234);

Integer iB = new Integer(“1234”);

long

Long

Long lA = new Long(1234);

Long lB = new Long(“1234”);

float

Float

Float fA = new Float(12.34f);

Float fB = new Float(“12.34f”);

double

Double

Double dA = new Double(12.34);

Double dB = new Double(“12.34”);


생성자는 위와 같이 해당하는 기본형 값을 줄 수도 있고 문자열로 줄 수도 있다. 문자열로 주는 경우 해당 데이터형의 형식에 맞아야 한다.


 박싱(boxing)이란 기본형을 참조형으로 변환하는 것이고 언박싱(unboxing)이란 반대로 참조형을 기본형으로 바꾸는 것이다. 그리고 JDK 1.5부터는 이것을 자동으로 해주는 기능이 추가되었다.


package tut02;
public class Tut02 {
   public static void main(String[] args) {
       Integer iA = new Integer(123);
       Integer iB = new Integer(123);
       
       int ia = (int)iA; //(1) 언박싱(unboxing)
       int ib = iB; //(2) 오토언박싱(auto unboxing)
       Integer iC = (Integer)456; //(3)박싱(boxing)
       Integer iD = ia; //(4)오토 박싱(auto boxing)
   }
}


위 예세서 (1)은 명시적으로 언박싱을 해주는 것이고 (2)는 자동으로 수행해 주는 것이다. 박싱의 경우도 자동으로 처리해 준다. 오토박싱과 오토언박싱은 대응되는 자료형 사이에만 일어난다는 점도 유의해야 한다.


 포장 클래스 객체간 연산도 가능하며 기본형과 포장형 간 연산도 가능하다.


package tut02;
public class Tut02 {
   public static void main(String[] args) {
       Integer iA = new Integer(123);
       Integer iB = new Integer(123);
       
       int ia = (int)iA; //(1) 언박싱(unboxing)
       int ib = iB; //(2) 오토언박싱(auto unboxing)
       Integer iC = (Integer)456; //(3)박생(boxing)
       Integer iD = ia; //(4)오토 박싱(auto boxing)
       
       Integer iE = iA + iB; // 포장형끼리의 연산
       Integer iF = ia - ib; // 기본형끼리의 연산 결과를 오토박싱
       int ic = ia * iB; // 기본형과 포장형 간 연산
   }
}


자바에서는 연산자가 오버로딩되지 않는다는 점을 생각하면 의아할 것이다. 하지만 이 코드는 내부적으로 포장형인 피연산자가 오토언박싱 되어서 기본형 끼리의 연산으로 수행되는 것이라고 이해할 수 있다.


 비교 연산도 가능하지만 내용물의 동치 여부를 검사할 때 ==기호대신 equals() 메소드를 이용해야 한다.


package tut02;
public class Tut02 {
   public static void main(String[] args) {
       Integer ia = new Integer(123);
       Integer ib = new Integer(123);
       Integer ic = new Integer(456);
       System.out.println("ia>=ib:"+(ia>=ib));
       System.out.println("ib>=ic:"+(ib>=ic));
       System.out.println("ia==ib:"+(ia==ib));
       System.out.println("ia.equals(ib):"+ia.equals(ib));
   }
}


ia>=ib:true
ib>=ic:false
ia==ib:false
ia.equals(ib):true


왜냐면 포장형고 객체이기 때문에 ==연산은 두 객체 인스턴스의 참조(주소값)을 비교하게 되는 것이다. 내용물의 동치 여부는 문자열 객체와 마찬가지로 equals() 메소드를 이용해야 한다.




Posted by 살레시오
,

라즈베리파이1에서는 netbeans 를 설치할 수는 있지만 사용이 불가할 정도록 느렸다. 라즈베리파이2에서는 어떤지 궁금해서 설치를 진행해보았다. 설치 방법은 정말 간단한데 오라클 홈페이지에서 리눅스용으로 다운로드를 받는다.


[그림 1] 홈페이지에서 리눅스용으로 선택한 후 JAVA SE 버전을 다운받는다.


그러면 사용자의 Download 디렉토리에 netbeans-8.0.2-javase-linux.sh 라는 파일이 다운로드되는데 명령창에서 다음과 같이 한다. (이 파일을 다 타이핑할 필요 없이 ne 까지만 치고 tab키를 누르면 자동완성된다.)


$sudo sh netbeans-8.0.2-javase-linux.sh


그러면 설치 대화창이 화면에 나타나고 그대로 진행하면 된다.


 설치가 끝났다면 사용자 디렉토리에 netbeans-8.0.2 디렉토리가 생성되고 그 안에 실행파일이 있다. <userHome>/netbeans-8.0.2/bin/netbeans 파일을 실행하면 IDE가 실행된다.


 잠깐 사용해 본 느낌은 의외로 잘 동작한다는 것이다. JDK8과 JVM도 무난하게 깔리고 잘 동작한다. 윈도에서 개발하던 도구 그대로 라즈베리파이(2)의 데비안 OS에서 사용할 수 있다는 것이 무척 신기하다.



Posted by 살레시오
,

 라즈베리파이2에서 무선랜을 설정하는 방법을 알아보자. 라즈비안에 무선랜을 반자동으로 설정해주는 Wifi_Config 가 없어서 쉘명령어로 설정을 해야하는데 비교적 간단히 할 수 있다.


 무선랜 동글을 꼽고 먼저 다음과 같은 명령어로 이것이 인식이 되는지 확인한다.


$sudo iwlist wlan0 scan


그러면 랜카드가 인식한 와이파이 리스트가 나오는데 검색된 무선 공유기의 ESSID 를 확인한다. 그리고 다음과 같은 화일을 nano 에디터로 연다.


$sudo nano /etc/network/interfaces


이 파일에 다음과 같이 내용을 추가한다.



여기서 wpa-ssid 옆에 문자열로 방금 전 검색한 ESSID를 입력하고 wap-psk 옵션에는 비밀번호를 입력한다.


이 파일을 저장하고 나오면 자동으로 설정이 적용되는데 만약 인터넷에 여전히 연결이 안 된다면 다음과 같이 무선랜을 껐다가 켠다.


$sudo ifdown wlan0

$sudo ifup wlan0


그러면 새로운 설정이 적용되어 무선 인터넷에 연결이 된다.



Posted by 살레시오
,