Search
Duplicate

자바를 자바 08(클래스 세부, call-by-value)

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Java
Scrap
태그
9 more properties

Creating an Array of Objects

class Employee{ private String name; public Employee(String name){ this.name = name; } public String getName(){ return this.name; } } public class Lecture{ public static void main(String[] args){ Employee m[] = new Employee[3]; m[0] = new Employee("Mario"); m[1] = new Employee("Luigi"); m[2] = new Employee("Toad"); System.out.println(m[0].getName()); } }
Java
복사

Instance Variable Instantiation

클래스 변수에 선언과 동시에 초기화 가능
class Employee { private String name = "Joe"; public void setName(String name) { this.name = name; } public String getName() { return this.name; } }
Java
복사

Default Initialization

만약 초기화가 아예 진행되지 않았다면? 그러면 클래스 자체적으로 default constructor가 발동하여 number : 0 / boolean : false / object : null 로 값이 초기화 된다.
하지만 local variable은 반드시 생성과 동시에 초기화 해주어야 한다.
class Employee { private int salary; public int getSalary() { return this.salary; } } public class Lecture { public static void main(String[] args) { Employee m = new Employee(); System.out.println(m.getSalary()); int local_var; System.out.println(local_var); // Error: local variable not initialized! } }
Java
복사

Final Instance variable

final 이라는 것은 constructor에서는 초기화 할 수 있지만 다른 메소드에서는 변경할 수 없는 변수를 이야기 한다.
class Employee{ priate final String name; public Employee(){ this.name = name; } public void setName(String name){ //this.name = name //에러난다. } }
Java
복사

Static Variable

static variable 은 클래스 자체에 소속되는 거고 객체별로 속해지는 것이 아님. 그렇기에 공유되고 있는 변수라고 생각할 수 있음.
class Employee{ //초기화 방법1 private static int lastId=0; //static variable //초기화 방법2 static{ lastId = 0; } private int id; //instance variable public Employee() { id = ++lastId; } public int getId() { return this.id; } public int getLastId() { return this.lastId; } # 이건 좋은 방법이 아님 } public class Lecture { public static void main(String[] args) { Employee m = new Employee(); Employee n = new Employee(); System.out.println(m.getId()); System.out.println(n.getId()); System.out.println(m.getLastId()); System.out.println(n.getLastId()); } }
Java
복사
출력결과 : 1 2 2 2
여기에서 주의할 것이 public int getLastId() { return this.lastId; } 이 함수인데, static variable을 method에서 접근하고 있다. 이러면 java 에서는 에러를 띄어준다.
왜냐하면 java의 garbage collector(gc) 때문이다. gc가 해당 인스턴스 메소드가 끝나는 시점에 메모리를 제거한다면 static variable도 메모리상에서 삭제될 수 있기 때문에 이는 매우 위험하다고 볼 수 있다.

Static Final Variable

static 이면서 final 인 변수
public class Math{ public static final double PI = 3.14159265358979323846; }
Java
복사
System.out 은 final variable이다.
public class System{ public static final PrintStream out; }
Java
복사

Static Method

클래스에 속해 있는 메소드. 해당 메소드를 호출하기 위햇 인스턴스를 생성할 필요가 없음.
대표 예시) Math.pow(2,5);

Static Variable ans Static Method

위에서 static variable 은 instance method에서 호출하면 안된다고 하였다. 왜냐하면 언제 에러가 발생할지 알 수가 없기 때문이다.
반대로 static method에서는 static variable을 호출하여도 된다. 또한 static method에서 static variable을 호출한다면 this 키우드를 사용하지 않아도 된다. 왜냐하면 this는 객체가 자기자신을 호출하는 것인데 static은 객체가 없기 때문이다.
class Employee{ private static int lastId=0; //static variable private int id; //instance variable public Employee() { id = ++lastId; } public int getId() { return this.id; } public static int getLastId() { return tlastId; } //이와 같이 실행하면 된다. }
Java
복사
이는 위에서 설명한 바와 동일한 garbage collector(gc) 때문이다.

Java : Call-by-Value

자바에서는 call-by-value를 사용한다.
동적할당이 아닌 단지 값만 삽입했다면 함수를 사용할 경우 값이 바꾸지 않는다.
public class Lecture{ public static void swap(int a,int b){ int temp = a; a=b; b=temp; } public static void main(String[] args){ int a1=10; int a2=20; swap(a1,a2); System.out.println(a1+" "+a2); } }
Java
복사
이경우에는 a1과 a2의 값은 바뀌지 않는다.
하지만 동적할당을 하는 뱅열은 경우가 달라진다.
public class Lecture{ public static void swap(int []x){ int temp = x[0]; x[1] = x[0]; x[0] = temp; } public static void main(String[] args){ int [] a = new int[2]; x[0]=10; x[1]=20; swap(x); System.out.println(x[0]+" "+x[1]); } }
Java
복사
이것의 결과물은 20,10 으로 삽입된 값이 달라지게 된다.
이는 동적할당된 메모리를 참고하엿 생기어난 결과물이다.
간단하게 말해서 동적할당, new를 사용했다면 인자로 값을 넘겨준다면 값이 바뀌게 된다.
하지만 자바에는 이런 연산조차 call-by-value라고 부른다. 다 말하는게 다르기는 하지만 가장 대표되는 의견은 결국 주소를 가르키는 변수가 가르키는 주소가 바뀐게 아니지 않느냐 이기 때문에 call-by-value를 주장하는 경우가 더 많다고 한다... 흠... 또다른 의견으로는 call-by-reference와의 구분은 중요치 않다고도 한다...
class Employee{ String name; public Employee(String name) { this.name= name; } } public class Ex08_04 { public static void changeName(Employee e,String newName) { e.name=newName; } public static void setName(String oldName,String newName) { oldName=newName; } public static void main(String[] args) { Employee m = new Employee("Peter"); System.out.println(m.name); changeName(m, "John"); System.out.println(m.name); setName(m.name, "James"); // 바뀌지 않는다. System.out.println(m.name); } }
Java
복사
또다른 예제로 객체 역시 객체 자체를 넘기어 주어야지 인자를 넘기어 주는 것으로는 바뀌지 않는다.

함수

추가적으로 java는 함수 호출방식이 매우 특이한데
public class Ex08_03 { public void swap(int a,int b) { int temp = a; a= b; b=temp; } public static void swap(int[] x) { int temp=x[0]; x[0]=x[1]; x[1]=temp; } public static void main(String[] args) { int x=10; int y=20; swap(x,y); System.out.println(x+" "+y); int[] a=new int[2]; a[0]=10; a[1]=20; swap(a); System.out.println(a[0]+" "+a[1]); } }
Java
복사
현재 첫번쨰 swap에는 static이 안붙은 것을 확인할 수 있고 실재로도 이 코드는 실행이 안된다. 이 이유는 main함수가 public static이기 때문에 발생하는 문제인데 static 함수는 반드시 static함수만을 호출할 수 있기 때문에 함수를 정의하고 사용하려면 함수 앞에 반드시 public static을 붙이어야만한다. 하다못해 private static이라도...