출처: http://notpeelbean.tistory.com/entry/JAVA-자바-프로그래밍시-자꾸-헛갈리는-것들-1
자바에서의 변수
자바의 변수는 8가지 기본형 변수(boolean, char, byte, short,int long, float, double)를 제외한 모든 변수는 참조형 변수이다.
(new를 이용하여 인스터스화를 해야하는 모든 변수들)
그렇기에 이런 인스턴스들 간의 대입연산(=)은 모두 Call by Reference 형태로 연산이 된다.
즉, 객체가 가진 값이 대입되는 것이 아닌 그 주소가 대입되는 것.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ArrayList<String> a1 = new ArrayList<String>(); a1.add( "abcdef" ); ArrayList<String> a2 = new ArrayList<String>(); a2 = a1; //Call by Reference //a2 = (ArrayList<String>) a1.clone(); //Call by Value a2.clear(); a2.add( "ghijk" ); System.out.println(a1.get( 0 )); System.out.println(a2.get( 0 )); < |
그렇기에 위의 코드의 결과는
ghijk
ghijk
가 나온다. 값이 아니라 주소가 넘어갔기에 나타나는 현상.
이를 값만 전달하려면 기본적으로 지원하는 clone 메소드를 이용하면 된다.
자바에서는 클래스로부터 객체를 만드는것을 인스턴스화(instantiate) 라 하며 객체를 (instance)라고 한다.
또한 인스턴스는 직접 다룰 수 있는것이 아니라 참조변수를 통해서만 다룰 수 있다.
ex>
TV t = new TV();
TV는 클래스. t는 참조 변수이다. new TV() 로 인스턴스가 생성되고, 생선된 인스턴스의 주소가 참조변수 t에 대입된다.
또한 하나의 참조변수는 하나의 인스턴스의 주소만을 저장 할 수 있다.
별 것 아니지만 굉장히 중요한 개념(특히 내가)
클래스변수, 인스턴스변수, 지역변수
변수의 종류 |
선언위치 |
생성시기 |
클래스변수 |
클래스 영역 |
클래스가 메모리에 올라갈 때 |
인스턴스변수 |
인스턴스 생성시 |
|
지역변수 |
메서드 영역 |
변수 선언문 수행시 |
클래스변수는 멤버변수중 static이 붙은 놈.
모든 인스턴스가 공유하는 변수, 인스턴스화를 안하고도 사용가능(클래스명.변수명 ex: TV.lcd)
참조 : http://rockdrumy.tistory.com/214
참고-static method 는 같은 클래스내의 인스턴스 변수나 인스턴스 메소드를 호출하지 못한다.
이유는 인스턴스멤버가 존재하는 시점에 클래스멤버는 항상 존재하나, 클래스멤버가 존재하는 시점에 인스턴스멤버가 존재할 수도 있고 존재하지 않을 수도 있기 때문이다.
http://blog.naver.com/rio_song/130108339020
자바에도 참조형 매개변수(reference type)이 있다.
Call by Reference를 위한 참조형 매개변수가 있댄다.
매개변수를 쓰는 곳에 Data a 이런식으로 쓰면 된다하네..(ex : static void change(Data a))
자바에는 포인터가 없대서 없는줄 알았는데.... 이게 뭐야 몰라 무서워...
업캐스팅(Up-casting) 과 다운 캐스팅(Down-casting)
업캐스팅 : 자손타입-> 조상타입 형변화 <형변환 생략가능>
다운캐스팅 : 조상타입->자손타입 형변화 <형변환 생략불가>
매개변수의 다형성
- 참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다
class Product 가 있고 이를 상속하는 자식클래스로 tv, com, audio가 있을때.
buy(tv t), buy(com c), buy (audio a) 등으로 각각의 타입으로 매개변수를 받는 메소드가 있다면
각각의 클래스는 Product에서 상속함으로
buy(Product p)
라는 하나의 메소드로 다 받을 수 있다.
ex>
buy(Product p){
money = money - p.price;
bonusPoint = bonusPoint + p.bonusPoint;
bonusPoint = bonusPoint + p.bonusPoint;
}
업캐스팅(up-casting)하위 클래스형에서 상위 클래스형으로 캐스팅 되는것.(자바는 모든것이 클래스)
class a()
class b extends a()
형태의 클래스 두개가 있다면
a c = new b();
형태로 b가 a로 업캐스팅 된다.
이때 a에 존재하는 메소드만 사용이 가능한다. b에만 존재하는 메소드에는 접근이 불가능(업캐스팅 되어서 제한됨)
그러나 b에서 a의 메소드가 오버라이딩 되었다면, 오버라이딩된 b의 메소드가 호출이 된다.
ex>
class Shape {
public void draw(){ //내용 생략 }
}
위의 저런 두가지 클래스가 있다고 할때
class Circle extends Shape{
public void draw(){ //내용 생략 }
}
Shape s = new Shape();
s.draw(); //Shape의 draw() 메서드 호출
Circle c = new Circle();
c.draw(); //Circle의 draw() 메서드 호출이런 결과가 나온다.
클래스, 추상클래스, 인터페이스 모두 동일하게 업캐스팅이 가능하다.
은닉, 보호, 오류감소 등의 목적으로 업캐스팅을 사용한다.
다운캐스팅은 업캐스팅한 것을 다시 돌려줄때 이용.
반드시 명시적 캐스팅을 해주어야한다 (변환할형) abc 등....
그리고 잘못하면 심각한 에러가 발생하니 주의할것.
int <-> String 형변환
String -> int
String s = "236222";
int i = Integer.parseInt(s);
int -> String
int i = 222333;
String s= Integer.toString(i);
문자열(String) 비교시 왜 equals를 써야 하는가?
String변수는 기본자료형 변수가 아니라 참조자료형 변수, 즉 객체이다. C로 생각하자면 포인터 변수나 마찬가지.
거기다 자바가가지는 리터럴 상수("abc" 처럼 ""안에 있는것)가 저장되는 공간의 특성 때문이다.
예를 들어 String s= "abc"; 라고 선언을 하면 "abc"가 메모리에 올라가고, s는 abc를 가르키는 주소가 저장된다.
그리고 이후에 생성되는 "abc"란 리터럴 상수는 모두 같은 주소를 갖게 된다.
s1="abc", s2="abc"하면 s1,s2 모두 같은 주소를 가르키게 된다는 것.
단 s1="abc"한후, s2= new String("abc")를 해버리면, new를 써버리면 "abc"가 올라가는 새로운 메모리가 생성된다.
s1, s2를 모두 출력하면 동일하게 "abc" 가 나오지만, 가르키는 주소가 다르므로
s1==s2는 false가 되는 것.
그렇기에 이를 제대로 비교하려면 equals 메소드를 사용해야 한다.
String 참조변수는 stack에 리터럴 상수는 haep메모리에 올라감. 이 heap메모리의 해시코드를 갖고 비교하는 equals메소드를 사용해야 원하는 결과를 얻을 수 있음.
'Programming > Java' 카테고리의 다른 글
for loop to iterate over enum in Java (0) | 2013.06.25 |
---|---|
나의 eclipse 설정 (key 포함) (0) | 2013.04.08 |
[펌] Eclipse 기본 사용법 (0) | 2013.04.02 |