본문 바로가기

JAVA공부(이것이 자바다)

java의 참조타입

함수의 구성 찾아보기

ctrl + 함수명클릭

 

 

 

 

 

JVM

JVM
OS
H/W

jvm은 자바가 설치된 폴더 안에 server 폴더 안에 jvm.dll라는 것을 os위에 돌려서 실행된다

JVM은 class파일을 실행 할때 코드변환을 할 때 딜레이가 걸린다.

 

 

프로세스

프로그램은 여러개 실행이 가능하다. 실행이 된 프로그램을 프로세스라고 한다. 프로세스를 실행하면 논리적으로 4GB의 PCB를 할당하게 되고 이 PCB는 프로세스가 실행되는 동안 필요한 내용을 저장한다. 

4GB의 할당은 논리적으로 되는 거니까 최대 4GB까지 사용할 수 있다는 것이지 실제로 4GB를 할당하지는 않는다. OS가 알아서 할당하고 프로그램도 있는대로 실행할 수 있다.

PCB구성

Data
code

프로세스를 실행하게 되면 RAM에 코드가 올라간다. 올라간 코드를 PCB의 code자리에 매핑하여 사용한다. 따라서 여러개의 같은 프로그램을 실행해도 RAM에는 하나의 코드만 올라간다.

 

 

 

클래스도 DATA+함수(코드)로 생각하면 JVM의 메모리 영역을 이해 할 수 있다.

메소드 영역에서 코드가 모두 실행되고 메소드 영역을 실행하면서 필요한 변수들을 스택영역에서 참조해서 쓰고 스택영역에서 참조타입변수는 힙영역을 참조한다.

메소드 영역
Static
메소드
생성자
스택영역
기본타입변수, 참조타입변수를 저장한다.
힙영역
new에 의해 선언된 객체를 저장한다.
 

{...}영역은 스택영역에 한 칸씩 들어간다. 따라서 함수들(지역변수, 인자,코드)이 스택영역에 들어가는 것!!

스택은 64KB크기로 아주 작아서 함수를 계속 호출할때 스택오버플로우가 발생할수 있다.

 

논리 / 물리

논리는 사용자가 코드를 알아보기 쉽게 하기 위해서 도움을 주는 부분이다. 하드웨어에 기록되지 않는다.

물리는 사용자가 코드를 작성하게 되면 메모리의 주소를 변수명이 대신하게 된다던가 할당받은 메모리 영역에 값을 적어넣어 하드웨어상에 기록되는 부분이다.

int(논리) a(물리)=10(물리)

class(논리), 클래스가 물리가 되려면 new 연산자를 통해 객체를 생성해야 비로소 물리가 될 수 있다.

 

함수명은 코드주소이다.

함수명은 메모리에 함수가 저장되어있는 부분의 주소에 이름을 붙여준 것이다. -> 결국 변수라는 뜻

 

우리가 함수명() 이렇게 소괄호를 같이 써주면 함수를 호출할 수 있다. 함수명만 쓰면 함수가 있는 곳의 주소만을 나타낸다.

 

 

문자열

문자열 객체에 저장되는 내용은 2가지 이다.

1. 저장되는 내용 -> 우리가 초기화하거나 대입해서 참조하는 곳의 메모리 영역에 기록된 것!

2. 문자열의 길이 -> 메모리 영역에 기록된 것의 크기를 지정된 byte크기로 나누기 해서 길이를 갖고 있다

길이 불러내는 거에 ()가 존재!!!!

문자열변수.length();

NullPointerException과 ""의 길이~

참조타입변수의 null은 ==과 != 로 확인 할 수 있다.

String arr1 ="";
arr1.length();// 0
String arr2 =null;
arr2.length();// NullPointerException 발생

 

Arrays.toString(arr); ->배열전체를 출력하고 싶을때 사용한다. 문자열, 숫자배열 다 된다.

 

문자열 조작 방법

 

replace()

기존 문자열은 그대로 두고, 대체한 새로운 문자열을 리턴한다. 왜냐? 문자열은 상수이기 때문에 변경 불가능하기 때문이다. 

문자열변수.replace("이전값","바꿀값");
"스트링".replace("이전값","바꿀값");

문자열 자르기

substring(index) - > index에서 끝까지 잘라내기

substring(startindex, endindex) - > start~end앞까지 잘라내기

String ssn = "880815-1234567";
String firstNum = ssn.substring(0,6);//880815
String secondNum = ssn.substring(7);//1234567

 

indexOf("문자열")

특정문자열의 위치를 찾을때 사용한다. 포함되어있지 않으면 -1을리턴한다.

이 문자열에 이거있냐??하고 쓸때는 0보다 큰지 확인한다.

String subject = "자바 프로그래밍"
int index = subject.indexOf("프로그래밍");//3

 

contains("문자열")

특정 문자열이 존재하면 true를 리턴하고 그렇지 않으면 false를 리턴한다. 이 함수는 내부적으로 indexOf를 사용한다.

boolean result = subject.contains("프로그래밍");//true

 

split("구분자")

구분자를 기준으로 문자열을 분리해서 문자열 배열에 넣는다.

	      String board = "번호,제목,내용,성명";
	      String[] arr = board.split(",");//{"번호","제목","내용","성명"}

 

배열

배열은 하나의 변수로 같은 자료형의 값들을 관리(연속된 공간)할때 사용한다. 배열에 한번 결정된 배열의 길이는 늘리거나 줄일 수 없다.

 

배열은 못바꾼다. ctrl+ 함수명해서 들어가보면 내부적으로 final이라는 상수로 선언되어 있음 확인할 수 있다.

 

배열 또한 문자열과 같이 내용과 길이가 저장되어있다

괄호가 존재하지 않음!

배열명.length//이렇게 길이를 불러다 쓸수있다.

자바의 다차원 배열은 길이를 다르게 줄수 있다.

int[][] scores ={
	{80,90,96},
    	{76,88)
  };

 

배열에 대입과 초기화

배열의 대입과 초기화를 구분할 줄 알아야한다. 대입해야 할 곳에 초기화를 해주면 개망~하기 때문이다.

 

초기화

변수 선언 시에만 쓸 수 있고{값,값,값,값}은 힙영역에 생성되고 변수는 스택영역에 생성되면서 힙영역의 주소를 가리키게 된다.

타입[] 변수 = {값,값,값,값};

변수에 초기화할때는 {  ,  ,  }로 값을 넣어주고 대입할때는 이렇게 써주면 안된다.

함수의 매개변수로 {  ,  ,  }로 쓰면 안된다!! 

우리가 함수를 선언할때 매개 변수를 두게 되는데 매개변수는 이미 함수가 생성되었을때 선언된 변수이다. 따라서 초기화가 아닌 대입을 해주어야한다!!!!

함수명({a,b,c})//이 방식은 절대 안됨!!

 

대입

배열 변수를 미리 선언한 후에는 값목록을 변수에 대입할 수가 없다.(초기화처럼 쓸수 없다는 뜻) 그래서 우리는 "new 자료형[]{  ,  ,  }"으로 힙영역에 배열을 생성한 뒤 이 주소 값을 대입해주어야한다.

변수 = new 타입[]{값, 값, 값, 값};

대입은 함수 호출시에 매개변수로 사용가능하다!!

printItem(new int[]{95, 85, 90});

 

 

native

native는 현재 코드에 가장 최적화되어 빠르게 돌아갈 수 있는 함수들 앞에 붙는다. 이 함수들은 os에서 제공하며 C언어로 구성되어 있기 때문에 ctrl+함수명을 통해 상세한 코드를 보아도 java코드 없이 함수명만 존재한다.

native를 사용하는 예에는 자바배열 복사가 있다.

자바에서 배열을 복사하기 위해 for문을 출력하게 되면 시간이 오래걸린다. 그래서 native 함수인 System.arraycopy(원본배열, 원본배열 복사 시작 인덱스, 새 배열, 새배열 붙여넣기 시작 인덱스, 복사할 항목수);로 구성된 함수가 있어서 갖다 쓰면된다.

System.arraycopy(Object src, int srcStart, Object dest, int destStart, int length);
//System.arraycopy(원본배열, 원본배열 복사 시작 인덱스, 새 배열, 새배열 붙여넣기 시작 인덱스, 복사할 항목수);

아래와 같이 코드가 없이 함수만 선언되어있다.

시간 확인 함수 System.nanoTime(), System.currentTimeMillis()

int[] oldArr = new int[10000];
int[] newArr = new int[10000];
	      
for(int i=0;i<oldArr.length;i++) {
	newArr[i]=(int)(Math.random()*1000);
}
	      
//long now = System.currentTimeMillis();//1000분의 1초;
long now = System.nanoTime();
	      
for(int i=0;i<oldArr.length;i++) {
	newArr[i]=oldArr[i];
}
	      

now = System.nanoTime()-now;
	      
System.out.println("1.실행시간 -> "+now);
	      
now = System.nanoTime();
	      
System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
	      
	      
now = System.nanoTime()-now;
	      
System.out.println("2.실행시간 -> "+now);

실행시간의 차이가 확연히 난다.

 

 

 

'JAVA공부(이것이 자바다)' 카테고리의 다른 글

클래스 이어서  (0) 2023.05.29
java참조타입 이어서  (0) 2023.05.26
java의 연산자와 조건문 반복문  (0) 2023.05.24
java의 변수  (0) 2023.05.23
java 설치와 사용  (0) 2023.05.22