JAVA

23-01-30(2) 자바 (system클래스, class 클래스, String 클래스)

모건이삼촌 2023. 1. 30. 17:31

toString 어떤 객체의 배열을 문자열로 정의하려고 할 때 문자열로 반환

hashCode는 13장 가서 설명

 

1. System 클래스

os와 관련된 기능들이 존재하는 클래스로 모든 멤버가 클래스 (변수, 메서드)

화면에 출력하거나 

 

exit()메서드는 프로그램을 강제 종료하는 기능이 있다. 파라미터에 매개변수값을 정수로 넣어주는데 이 정수는 운영체제에 넘겨주는 코드로 어떤 이유로 종료되었는지 알려주는 코드값이며 0은 정상적으로 종료되었다는 메세지이다.

 

콘솔프로그램을 실행 후 종료할때 Ctrl+c를 누르면 종료되고 Ctrl+break를 누르면 멈춘다.

 

System.currentTimeMillis() 현재 시간을 볼 수 있는 클래스

출력하게 되면 Epoch-Time으로 나오는데 1970년 1월 1일 00시00분00초 부터의 밀리세컨드로 출력된다.

Epoch-Time을 잘 못쓰면 자바에서의 날짜표기가 힘들어진다.

 

2. class 클래스

class 클래스는 클래스를 메모리에 로드하거나 클래스나 인터페이스의 이름, 생성자, 필드, 메서드의 정보를 확인할 수 있는 클래스이다.

 

클래스의 객체를 얻는방법은

1) 객체를 생성하는 방법

2) 문자열 주소를 이용해서 생성하는 방법

3) 클래스 리터럴을 사용

클래스 리터럴이란 클래스명.class

 

package chapter12;

import java.lang.reflect.Method;

public class ClassTest {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException  {
		ClassTest test1 = new ClassTest();
		
		// 1번 방법 : 이미 만들어진 인스턴스를 통해 생성
		Class c1 = test1.getClass(); 
		
		// 2번 방법 : forName메서드를 통해 생성 
		Class c2 = Class.forName("chapter12.ClassTest");
		
		// 3번 방법 : 클래스 리터럴을 통해 생성
		// 용도와 목적에 따라서 쓰일수 있음.
		Class c3 = ClassTest.class;
		
		Method[] methods = c3.getMethods();
		for(Method m : methods) {
			System.out.println(m.getName());
		}
		
		Object o = c3.newInstance();
		System.out.println(o);
		
		
	}

}

실행결과

 

main

wait

wait

wait

equals

toString

hashCode

getClass

notify

notifyAll

chapter12.ClassTest@4a574795

※  Method, Function(함수) 구분

1. Method

 메서드를 호출하기 위해선 호출에대한 근거(매개체)가 필요함

 ex) 인스턴스 메서드를 호출하기 위해선 인스턴스가 필요하고 클래스메서드를 호출하려면 클래스가 필요함

 

2. Function

 함수는 매개체가 필요없음

 함수식 호출은 길어지면 길어질수록 문제가 생겨 유지보수가 힘듬

 

 

2. String 클래스

문자열을 다루는 클래스이며 문자열을 기본자료형으로 정의하지않고 클래스로 정의한 이유는 문자열과 관련된 여러가지 기능을 갖는 메서드까지 포함하기 위해서다

 

특징

 1) 다른 클래스와 다르게 new 키워드가 아니라 '=' 대입연산자로 객체를 생성할 수 있음

 2) + 더하기 연산이 가능한 클래스이다.

 3) 기본자료형과 + 연산을 하게되면 기본자료형도 String으로 자동 형변환된다.

 

package chapter12;

public class StringTest {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		String str3 = new String("abc");
		String str4 = new String("abc");
		
		
		// str1과 str2는 같은가
		System.out.println(str1 == str2);
		System.out.println(str1 == str3);
		System.out.println(str3 == str4); //인스턴스를 새로 만들었으니 다름
	}

}

실행 결과

 

true

false

false

 

str1과 str2의 "abc"는 JVM 최상단 상수풀에서 관리되고 있는데 서로 같은값을 바라보고 있어 true라는 값을 출력하고

str3와 str4는 새로운 인스턴스를 생성해서 JVM 힙의 영역에서 관리되어있기 때문에 서로 false가 출력된다

예를들어 상수풀에서 관리되는 "abc"의 주소를 0x100이라 하고 str3의 주소값 0x200안에 0x100을 담고있다.

str4도 str3와 같이 str4의 주소를 0x300이라하고 상수풀에서 관리되는 "abc" 즉 0x100의 값을 담고있기 때문에

겉을 감싸고 있는 주소값 0x200과 0x300을 비교하여 false를 출력하게 되는것이다.

 

※ 문자열의 특징
 1) 불변성 (변하지않음)
 2) 고유저장소 (상수풀 // 클래스상수를 관리하는곳이며 메서드영역에 있다.) (문자열풀 안에서 문자열 리터럴이 관리된다)

 

위의 예에 있는 0x100을 비교하려면 equals()메서드를 사용하면 된다. 아래 예제를 보자

 

package chapter12;

public class StringTest {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		String str3 = new String("abc");
		String str4 = new String("abc");
		
		
		// str1과 str2는 같은가
		System.out.println(str1 == str2);
		System.out.println(str1 == str3);
		System.out.println(str3 == str4); //인스턴스를 새로 만들었으니 다름
		
		// equals를 사용하여 비교
		System.out.println(str1.equals(str2));
		System.out.println(str1.equals(str3));
		System.out.println(str3.equals(str4));
	}

}

실행 결과

 

true

false

false

true

true

true

 

2-1. StringBuffer

변경에 대한 빈도가 많을수록Buffer를 사용하면 성능이 향상된다.
package chapter12;

public class StringTest2 {
	public static void main(String[] args) {
		
		long start = System.currentTimeMillis(); // 시작시간
		String s = "";
		
		for(int i=0; i<300_000; i++) {
			s += "0";
		
		}
		long end = System.currentTimeMillis();
		
		System.out.println(end - start + "ms");
		
	}

}

 실행 결과

8304ms

package chapter12;

public class StringTest2 {
	public static void main(String[] args) {
		
		long start = System.currentTimeMillis(); // 시작시간
		String s = "";
		StringBuffer buffer = new StringBuffer(s);
		for(int i=0; i<300_000; i++) {
//			s += "0";
			buffer.append("0");
		}
		long end = System.currentTimeMillis();
		
		System.out.println(end - start + "ms");
		System.out.println(buffer.toString().length());
	}

}

실행 결과

 

22ms

300000

 

StringBuffer를 사용하면 엄청난 성능 향상과 메모리 효율을 높일 수 있다.

 

반환타입

 

p.316의 표 삽입

 

package chapter12;

import java.util.Arrays;

public class StringTest3 {
	public static void main(String[] args) {
		String str = "abcdeabcde";
		System.out.println(str.indexOf("c")); // 좌측인덱스 부터 세서 찾음 (2번인덱스)
		System.out.println(str.indexOf("c",4)); // 좌측인덱스 2번 + 4번 
		System.out.println(str.lastIndexOf("c")); // 우측인덱스 부터 세서 찾음
		System.out.println(str.lastIndexOf("f")); // 찾지못해서 -1이 나옴
		
		System.out.println(str.substring(4)); // 이상 미만
		System.out.println(str.substring(4, str.length())); //str.length()는 생략되어있음
		System.out.println(str.substring(4, 7));
		
		// 순차탐색시 처음 만나는 c의 위치부터 끝까지 문자열을 자르시오
		System.out.println(str.substring(str.indexOf("c")));
		
		// 문자열을 대문자로 변환하여 리턴
		System.out.println(str.toUpperCase());
		
		// 매개변수 ""로 시작하면 true 아니면 false
		System.out.println(str.startsWith("ab"));
		System.out.println(str.startsWith("bc"));
		
		// 내부위치 탐색 
		System.out.println(str.contains("ea"));
		System.out.println(str.contains("eac"));
		
		// a를 f로 변경
		System.out.println(str.replace("a", "f"));
		// 첫번째 a를 f로 변경
		System.out.println(str.replaceFirst("a", "f"));
		
		// 구분자를 통해서 문자열 배열로 생성
		System.out.println(str.split("")[2]);
		// 전부 배열 인덱스값으로 입력
		System.out.println(Arrays.toString(str.split("")));
		// c를 컴마처럼 사용하여 배열로 생성
		System.out.println(Arrays.toString(str.split("c")));
		
		// abcde에 대한 char 타입의 배열
		char[] chs = str.toCharArray();
		String s2 = new String(chs);
	}

}

실행 결과

 

※ 과제

		String url = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%96%91%EC%B0%AC%EC%9A%A9";
		// https : 프로토콜
		// search.naver.com : 도메인
		// search.naver : 파일명
		// where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EC%96%91%EC%B0%AC%EC%9A%A9 : 쿼리스트링
		// 쿼리스트링은 이름과 값이 쌍으로 되어있음 &과 = 로 구분 위의 쿼리스트링은 5쌍으로 되어있음
		
		// 과제