자바1주차
자바의 특징
간단함
자바는 c++에 가깝지만 훨씬 간단하다. 자바는 고급 언어들에 들어 있는 여러 가지 요소들 중에서 반드시 필요하지 않다고 생각된 부분들은 모두 제거했다.
객체 지향적임(Object-oriented)
자바는 숫자(int, float, long등)나 논리값(true, false)을 제외한 거의 모든 것이 객체로 구성되어 있다. 실제로 자바는 Object 클래스에서 모든 클래스를 파생한다.
인터프리터 언어(Interpreted)
자바는 정확하게 말하면 컴파일 언어인 동시에 인터프리티 언어이다. 자바는 먼터 텍스트 소스를 컴파일하여 2진 파일(클래스 파일)로 만든 다음 런타임이 클래스 파일을 인터프리트하면서 실행한다. 먼저 시스템에 무관한 2진 파일을 만듬으로써 자바는 컴파일 언어에 가까운 속도와 시스템 독립성을 동시에 얻을 수 있었다.
강력하다(robust)
자바는 포인터 연산을 지원하지 않는다. 이는 잘못된 주소를 가르킬 가능성을 사전에 없앤 것이다. 자바는 모든 메모리 접근을 자바 시스템이 관리하고 제한하며 또한 예외 핸들링을 하여 시스템 붕괴의 우려가 없다. 예를 들어 자바는 리소스 관리(garbage collection)를 하는데 사용이 끝난 리소스를 시스템 메모리에서 삭제하는 방식을 채택하고 있어 메모리 누출에 대한 고민을 프로그래머가 할 필요가 없다.
안전하다(Secured)
자바는 포인터 개념이 없고 유형 정의가 강고하여서 실행 전에 클래스 파일을 이용한 프로그램의 검사가 가능하다. 자바는 프로그램 작성 시 자료형 타입에 굉장히 민감하다. 자바는 일단 컴파일만 되면 실행 시 오류가 발생하는 경우가 다른 언어에 비해 현저히 낮다. 컴파일만 되면 코드에 결정적인 문제는 없는 것이다.
플랫폼 독립적이다(Platfrom independent)
자바의 실행 파일은 이진 코드(클래스) 파일이다. 따라서 자바 런타임이 설치된 시스템에서는 어디서나 자바 프로그램을 실행할 수 있다. 자바에는 많은 특징이 있지만 가장 큰 특징이라면 한번 작성한 프로그램은 os에 상관없이 어디서든 돌려볼 수 있다는 점이다. 이것은 자바 프로그램이 Virtual Machine에 의해서 실행되기 때문이다. 처음에 이 방식은 Virtual Machine을 실행시켜서 프로그램을 돌려야 하기 때문에 좀 느리고 부담스러 웠지만 지금은 하드웨어의 눈부신 발전과 여러 기술들의 개발로 이러한 단점들이 대부분 사라졌다.
멀티 쓰레딩을 지원한다(Multithreaded)
멀티 쓰레드를 지원할 경우 하나의 프로그램 단위가 동일한 쓰레드를 동시에 수행할 수 있다. 특히 자바는 멀티 프로세서 하드웨어를 지원하도록 설계되었으므로 멀티 CPU 시스템에서 높은 효율을 낼 수 있다.
동적이다(Dynamic)
자바 인터페이스를 이용하면 하나의 모듈을 갱신할 때 다른 모듈을 모두 갱신할 필요가 없다. 이것은 인터페이스가 모든 인스턴스 변수와 도구의 실행문을 배제한 채 객체 상호간의 상호작용을 정의하기 때문이다.
자바 컴파일
![[스크린샷 2022-11-03 오후 2.29.25.png]]
소스코드(MyProgram.jave)를 작성한다.
컴파일러(Compiler)는 자바 소스코드를 이용해서 클래스 파일(MyProgram.class)을 생성한다. 컴파일 된 클래스 파일은 Java Vm(Java Virtual Machine)이 인식할수 있는 바이너리 파일이다.
Java VM(JVM)은 클래스 파일의 바이너리 코드를 해석하여 프로그램을 수행한다.
Myprogram 수행 결과가 컴퓨터에 반영된다.
class파일을 만드는 이유
c, c++과 같은 언어는 컴파일 된 실행 파일을 모든 운영체제에서 동일하게 사용하는 것이 불가능하다. 윈도우에서 컴파일한 프로그램을 리눅스에서 사용할 수 없다는 얘기이다. 이것은 자바의 JVM과 같은 중간 단계의 역할을 수행하는 것이 없기 때문인데 이 부분에서 서로의 장단점이 명확하게 나누어 진다.
c, c++등의 언어에서 만들어진 실행파일은 JVM같은 중간단계를 거치지 않기 때문에 빠른 속도로 수행된다. 하지만 운영체제마다 별도의 실행파일을 작성해야 한다는 단점이 있다. 반대로 자바는 JVM이라는 중간 단계가 있으므로 C등의 언어보다 속도가 느리다. 하지만 한번 작성한 클래스 파일은 어떤 OS에서라도 사용할 수 있다는 장점이 있다. 한번 작성한 것을 널리 재활용하는 것이 자바의 가장 큰 특징이자 가장 큰 장점이라고 할 수 있다.
문자열(String)
원시(primitive) 자료형
이전에 살펴보았던 int, long, double, float, boolean, char 등을 자바는 원시(primitive)자료형 이라고 부른다. 이런 primitive 자료형은 new 키워드로 그 값을 생성할 수 없다.
primitive 자료형은 다음과 같이 리터럴(literal)로만 값을 세팅할 수 있다.
원시 자료형의 Wrapper 클래스
int, long , double, float, boolean, char 등의 원시 자료형은 다음처럼 각각에 대응하는 Wrapper 클래스들이 존재한다. ![[스크린샷 2022-11-03 오후 3.35.41.png]]
원시 자료형 대신 Wrapper 클래스를 사용하면 값 대신 객체를 주고 받을 수 있어 코드를 객체 중심적으로 작성하는데 유리하다. 또한 멀티스레딩 환경에서 동기화를 지원하기 위해서는 Wrapper 클래스가 반드시 필요하다.
문자열 내장 메소드
equals
equals는 두개의 문자열이 동일한지를 비교하여 결과값을 리턴한다.
String a = "hello";
String b = "java";
String c = "hello";
System.out.println(a.equals(b)); // false 출력
System.out.println(a.equals(c)); // true 출력
문자열을 비교할때는 반드시 equals를 사용해야 한다. ==연산자를 사용할 경우 다음과 같은 경우가 발생할 수 있다.
String a = "hello";
String b = new String("hello");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
문자열 a와 b는 모두 "hello"로 같은 값이지만 equals를 호출했을 때는 true를 == 연산자를 시용했을 때는 false를 리넡한다. a와 b는 값은 같지만 서로 다른 객체이다. == 은 두 개의 자료형이 동일한 객체인지를 판별할 때 사용하는 연산자이기 때문에 false를 리턴한다.
indexOf
indexOf는 문자열에서 특정 문자가 시작되는 위치(인덱스)를 리턴한다.
String a = "Hello Java";
위와 같은 a 문자열에서 "Java"라는 문자열이 시작되는 위치를 알고 싶은 경우 indexOf를 다음과 같이 사용할 수 있다.
String a = "Hello Java";
System.out.println(a.indexOf("Java")); // 6 출력
"Hello Java" 라는 문자열에서 "Java"라는 문자열은 일곱번째 문자부터 시작이다. 결과 값으로 6이 나온 이유는 자바는 숫자를 0부터 세기 때문이다.
contains
contains는 문자열에서 특정 문자열이 포함되어 있는지의 여부를 리턴한다.
String a = "Hello Java";
System.out.println(a.contains("Java")); // true 출력
charAt
charAt은 문자열에서 특정 위치의 문자(char)를 리턴한다.
String a = "Hello Java";
위와 같은 a 문자열에서 "J"라는 문자는 6번째 인덱스에 위치한 문자이다. 6이라는 숫자로 "J"라는 문자를 얻기 위해서는 다음과 같은 charAt을 사용한다.
String a = "Hello Java";
System.out.println(a.charAt(6)); // "J" 출력
replaceAll
replaceAll은 문자열 중 특정 문자열을 다른 문자열로 바꾸자 할 때 사용한다.
String a = "Hello Java";
System.out.println(a.replaceAll("Java", "World")); // Hello World 출력
"Hello Java" 라는 문자열에서 "Java"rk "World"로 바뀜
substring
substring은 문자열 중 특정 부분을 뽑아낼 경우에 사용한다.
String a = "Hello world";
Systme.out.println(a.substring(0, 4)); // Hell 출력
위처럼 substring(시작위치, 끝위치)와 같이 사용하면 문자열의 시작위치에서 끝위치 까지의 문자를 뽑아내게 된다. 단 끝위치는 포함이 안된다는 점에 주의하자
toUpperCase
toUpperCase는 문자열을 모두 대문자로 변경할 때 사용한다.
String a = "Hello Java";
System.out.println(a.toUpperCase()); // HELLO JAVA 출력
split
split 메소드는 문자열을 특정 구분자로 분리하는 메소드이다.
String a = "a:b:c:d";
String[] result = a.split(":"); // result는 {"a", "b", "c", "d"}
문자열 포매팅
문자열에서 또 하나 알아야 할 것으로는 문자열 포매팅(Formatting)이 있다. 문자열 안의 특정한 값을 바꿔야 할 경우가 있을 때 이것을 가능하게 해주는 것이 바로 문자열 포매팅 기법이다.
문자열 포매팅 따라 하기
1. 숫자 바로 대입
System.out.println(String.format("I eat %d apples.", 3)); // "I eat 3 apples." 출력
문자열 포매팅은 String.format 메소드를 사용한다. 위 예제의 결괏값을 보면 알겠지만 위 예지는 문자열 안에 정수 3을 삽입하는 방법을 보여 준다. 문자열 안에서 숫자를 넣고 싶은 자리에 %d 문자를 넣어 주고, 삽입할 숫자 3은 두번째 파라미터로 전달한다. %d는 문자열 포맷 코드라고 부른다.
2. 문자열 바로 대입
System.out.println(String.format("I eat %s apples.", "five")); // "I eat five apples." 출력
문자열 안에 또 다른 문자열을 삽입하기 위해 앞에서 사용한 문자열 포맷 코드 %d가 아닌 %s를 쓴다.
3. 숫자 값을 나타내는 변수로 대입
int number = 3; System.out.println(String.format("I eat %d apples.", number)); // "I eat 3 apples." 출력
4. 2개 이상의 값 넣기
int number = 10;
String day = "three"; // "I ate 10 apples. so I was sick for three days." 출력
System.out.println(String.format("I ate %d apples. so I was sick for %s days.", number, day));
2개 이상의 값을 넣으려면 파라미터로 여러개를 전달하면 된다.
문자열 포맷 코드
![[스크린샷 2022-11-03 오후 4.59.07.png]]
system.out.printf
String.format 메소드는 포매팅된 문자열을 리턴한다. 따라서 포매팅된 문자열을 출력 하려면 System.out.println 메소드를 함께 사용해야 한다.
하지만 System.out.printf 메소드를 사용하면 String.format 메소드 없이도 동일한 형식으로 포매팅된 문자열을 출력할 수 있다.
StringBuffer
StringBuffer는 문자열을 추가하거나 변경 할 때 주로 사용 하는 자료형이다.
append
다음은 StringBuffer 객체를 생성하고 문자열을 생성하는 예제이다.
StringBuffer sb = new StringBuffer(); // StringBuffer 객체 생성
sb.append("hello");
sb.append(" ");
sb.append("jump to java");
String result = sb.toString();
System.out.println(result);
결과값은 hello jump to java이다.
StringBuffer 자료형은 append 메소드를 사용하여 계속해서 문자열을 추가해 나갈 수 있다.
위 예제를 String 자료형만 가지고 표현하면 다음과 같이 작성할 수 있다.
String result = "";
result += "hello";
result += " ";
result += "jump to java";
두 개 예제의 결과는 동일하지만 내부적으로 객체가 생성되고 메모리가 사용되는 과정은 다르다.
첫번 째 예제의 경우 StringBuffer 객체는 한번만 생성된다. 두번 째 예제는 String 자료형에 + 연산이 있을 때마다 새로운 String 객체가 생성된다(문자열 간 + 연산이 있는 경우 자바는 자동으로 새로운 String 객체를 만들어 낸다). 두번 째 예제에서는 총 4개의 String 자료형 객체가 만들어지게 된다.
String 자료형은 한번 값이 생성되면 그 값을 변경할 수가 없다. 이렇게 값을 변경할 수 없는 것을 immutable 하다고 한다. trim, toUpperCase 등의 메소드를 보면 문자열이 변경되는 것 처럼 생각 될 수도 있지만 해당 메소드 수행 시 또 다른 String 객체를 생성하여 리턴할 뿐이다. 하지만 StringBuffer는 이와 반대로 값을 변경할 수 있다(mutable 하다). 즉 한 번 생성된 값을 언제든지 수정할 수 있다.
StringBuffer 자료형은 String 자료형보다 무거운 편에 속한다. new StringBuffer()로 객체를 생성하는 것은 일반 String을 사용하는 것보다 메모리 사용량도 많고 속도도 느리다. 따라서 문자열 추가나 변경등의 작업이 많을 경우에는 StringBuffer, 문자열 변경 작업이 거의 없는 경우에는 그냥 String을 사용하는 것이 유리하다.
StringBuffer와 비슷한 자료형으로는 StringBuilder가 있다. StringBuilder의 사용법은 StringBuffer의 사용법과 동일하다. StringBuffer는 멀티 스레드 환경에서 안전하다는 장점이 있고 StringBuilder는 StringBuffer보다 성능이 우수한 장점이 있다. 따라서 동기화를 고려할 필요가 없는 상황에서는 StringBuffer보다는 StringBuilder를 사용하는 것이 유리하다.
insert
insert 메소드는 특정 위치에 원하는 문자열을 삽입할 수 있다.
substring
substring 메소드는 String 자료형의 substring메소드와 동일하게 사용된다.
Last updated