반응형
<ex) Person lee = new Person();으로 생성할때, setter method 로 값을 담는데.
<태어나서 기본적으로가지고있어야될값들이 있을텐데 그게없고, 나중에넣는다는게 이상함.<이름은 나중에 지어주는거니까 맞는데,
<그래서 setter method와 처음부터 넣어주는 2가지로 나누어 진다.
<미리넣고 싶을때,처음부터 갖고있고 싶을때 생성자사용.
<객체가 생성 되었을때 값을 넣고 나오는게 있을텐데 그때쓰는것
<라면클래스도 마찬가지 처음부터 빈봉지..?이상함
*생성자(Constuctor)
-
객체가 생성될 때 가지고 있어야할 기본값(객체초기화값)이나 수행될코드를 정의하는 (부분인데 분류상 메소드) 메소드의 일종
-
<생긴건메소드랑같게생김 / 생성자는오버로딩지원
-
반환형이 없다
-
오버로드 지원 (객체생성을 다양하게 할수 있다)
-
클래스명과 동일하게 작성
-
<모든클래스 는 생성자를다 가짐 없는 클래스는 존재할수없음 private라보이지않는것
-
<기본생성자다가짐
-
개발자가 생성자를 하나도 정의하지않으면컴파일러가<초기값은 실행기가>(인자없는) 매개변수없는 기본생성자(디폴트 컨스터럭트)를 무조건 생성해준다.
-
=> 기본생성자의 접근지정자는 클래스의 접근지정자를 따라간다.
-
<생성자는메소드쩜 이케안불러지고
-
생성자는 객체를 생성할 때만 호출된다 (method 호출하듯이 직접 호출할 수 없다)
-
this를 사옹하면 내클래스의 다른 생성자를 호출할 수 있다.
-
<개발자가 생성자를 하나라도 만들면 안해준다. 없을때 까먹었구나 하고 만들어줌
-
문법)
접근지정자 생성자명(parameter...){
}
-
접근지정자)
-
public : 클래스 외부에서 객체생성 가능
-
protected : 동일패키지의 다른 클래스에서 객체 생성가능 / 패키지가 다르다면, 자식클래스만 객체 생성 가능
-
private : 클래스 안에서만 객체 생성 가능(싱글턴?패턴 을 적용해서 클래스를 만들고 싶다면 프라이빗 준다.)=>(Singleton pattern적용)
-
default : 아무것도 붙이지 않는것으로 동일 패키지의 다른 클래스에서 객체생성이 가능하지만, 패키지가 다르다면 객체생성 불가능
-
<퍼블릭이나 프라이빗 제일 많이 쓴다.
-
<생성자를 하나도 안만ㄷ르었엇 할땐 클래스의 접근지정자를 따라간다. 라면의 자동생성된 접근지정자는 퍼블릭이 되었을것
-
기본생성자의 접근지정자는 클래스의 접근지정자를 따라간다.
-
ex)
public class Marker{
public Marker(){
color = "검은색";
cap=1;
body=1 ;
}//생성자
public void setColor(String s){
}
public Marker(String color, int cap, int body){
this color = color;
this cap= cap;
this body= body;
}//생성자의 오버로딩
} |
클래스면 객체명 = new 생성자();
Marker m = new Marker();//검은색
m.setColor("빨간색");//검은색을 만들어놓고 빼고 빨간색을 넣는격
Marker ml = new Marker("빨간색" , 1,1);
//생성자의 오버로딩으로 다형성
//객체가 다르게 만들어진다.
|
<원래 객체 생성 할때 이렇게 불려지는 것이었다.>
<디컴파일러 : 클래스파일을 자바로 (배포될땐 클래스 파일로 배포되는데) 자바소스를 보고싶을때 사용>
<원래 코드로 되돌려 만들어진 프로그램의 취약점 찾기 : 리버싱 / 크랙도 리버싱의 일종
<클래스파일은 바이트 코드로 사람이 알아볼수 없는데, 그걸 알아보기 위해 소스코드로 바꿈.
<기본생성자 : 소스단계에 없어도 디컴파일러로 보았을때 생성되어있다. 컴파일러가 생성해 줌을 알수 있음
<API 에서 사용되는 모습..>
<오버로딩이 잘되어있음을 알수 있다.>
<생성자 없는 클래스가 아니라 프라이빗이라 밖에서 안보이는것 뿐=>없으면 존재할수 없다.>
<만든생성자를 모두 주석처리하고 기본생성자가 생긴모습>
<생성자를 만들고 기본생성자가 없어진 모습=>하나정의하고 나니 기본생성자가 사라짐.
<먼저한 코드들 호출부분의 setter method부분을 생성자로 고쳐봄>
<닥만들어서 잘 만들어졌는지 봄>
<생성자란~? 객체 생성시 기본값들을 넣어주는 부분~~
<생성자는 직접호출이 되지 않고 this 사용시 호출할수 있다고,,
*this
-
생성자를 호출하거나, heap의 주소(생성된 객체의 주소)를 가지는 keyword <용법2가지
-
method 형식과 keyword 형식으로 사용할 수 있다.
-
method 형식)
-
생성자를 호출할 때
-
keyword 형식)
-
생성된 객체의 주소를 사용할 때.
-
this method 형식)
-
내 클래스의 오버로딩(Overloding)된 생성자를 호출할 때 사용.
-
<규칙을 반드시 지켜서 작성해야한다.
-
<생성자의 첫번째 줄에서 꼬옥(슈퍼자리에)
-
<생성자를 부른다.
-
규칙 : 생성자의 첫번째 줄에서만 사용가능.
-
문법)
this(); //기본생성자를 호출할때 사용.
this(인수값,,,); //인자있는 생성자를 호출할 때 사용.
<재귀호출이 되면 Error <생성자의 재귀호출 불가.
ex)
public class Test{
public Test(){
}
public Test(int i){
}
}
Test t = new Test();
이때 기본생성자에서 인자있는 생성자를 부르고 싶으면
public class Test{
public Test(){
this(11);
}
public Test(int i){
}
}
Test t = new Test();
<기본생성자를 불리고 인자있는생성자를 바로 부른뒤 일을 하고 닫힘괄호로 다시 기본생성자로 돌아가
<나머지 돌고 닫힘괄호만나 호출한 곳으로 돌아간다.
public class Test{
public Test(){
}
public Test(int i){
this();
}
}//요렇게도 해보고~
<만약 둘다 서로를 부르고 있다면 재귀호출이되어 프로그램이 끝나지 않는다. 그래서 아예 프로그램에서 막아 놓았는데 그래서 Error
<재귀호출의 가능성이 있거나 그안에서 나를다시 부른다면 바로 이클립스에서 Error 쓰고싶어도 쓸수 없다.
<자바는 재귀호출 Error
<서로계속 불러 Error>
<이 순으로 돌게 되고 this로 다른생성자를 호출가능>
<this 의 사용으로 이렇게도 줄일수 있다. >
<생성자를 알았더니 사용하는쪽의 코드가 간단해졌고
<this를 알았더니 생성하는곳의 코드가 간단해짐
-
this method 형식)
-
<하기전에 콜바이벨유와 콜바이레퍼런스 알아야한다.<C에대한 이야기지로 자바도 그런 성격이지만 자바는 확인할 길이 없다
*Call by value
-
method의 매개변수를 기본형데이터형으로 정의하면 값이 복사되어 넘어간다. (전달된다.)
-
<복사된 값으로 계속 돌고 원본값이 바뀌지 않는것?
-
<클래스 스트링 배열로 저장하면 주소가 그대로 저장(주소는 딱 하나인데 하나가지고 쓰는것)
ex)
class Test{
public void swap(int i, int j){
int temp=0;
temp = i;
i=j;
j=temp
System.out.println("i="+i",j="+j);//300 100
}
public static void main(String[] args){
int i=100,j=300;
S.o.p(i+" "+j);//100 300
Test t = new Test();
t.swap(i,j);
sop(i+""+j);
}
}
//복사된 값이라 원본에 영향을 끼치지 않는다.
//복사된종이에 낙서된다고 원본에 낙서되지 않음=>Call by value
|
int i=100, j=300
temp][0]
i][100
temp][100
j][300
i][300
temp][100
j][100
//매개변수로만 놀고 사라짐 |
|
ex)
class Test{
public void swap(int i, int j){
int temp=0;
temp = i;
i=j;
j=temp
System.out.println("i="+i",j="+j);//300 100
}
public static void main(String[] args){
int i=100,j=300;
S.o.p(i+" "+j);//100 300
Test t = new Test();
t.swap(i,j);
sop(i+""+j);
}
}
//복사된 값이라 원본에 영향을 끼치지 않는다.
//복사된종이에 낙서된다고 원본에 낙서되지 않음=>Call by value |
public static void main(String[] args){
int i=100,j=300;
S.o.p(i+" "+j);//100 300
Test t = new Test();
t.swap(i,j);
sop(i+""+j);
} |
int i=100,j=300;
[i][100]
[j][300]
[t][i=100,j=300] |
| |
method(static변수 |
stack(local변수 |
heap(instance변수 | |
JVM |
*Call By Reference
-
method의 매개변수를 참조형 데이터형으로 정의하면 하나의 주소가 그대로 넘어간다.(주소는 유일)
-
<건드리면 바뀐다. 원래의 값이~!
ex)
class Test{
int i;//만약 int가 private였으면 밖에서 접근이 안되야 하는데
//배열 일때에는 getter로 써서 내보내면 public이 되어 콜바이레퍼런스때문에 변경됨...배열시 다시
int j;//인스턴스 변수라 쓰려면 객체화
public void swap(Test t){
//이 클래스로 i와 j에 접근
int temp = 0;
temp = t.i;
t.i=t.j;
t.j=temp;
s.o.p("swap 안에서"+i+" "+j);//200 100
}
public static void main(String[] args){
Test t = new Test();
t.i=100;
t.j=200;
s.o.p(t.i+" "+t.j);/100 200
t.swap(t);//그 주소를 그대로 갖고 가서 건드렸기 때문에 변경된다.
s.o.p(t.i+" "+t.j);//200 100
}
} //<복사와 주소의 차이 참조형데이터형일떄에는 값의 변경을 주의해야한다. =>배열 주의...
*Keyword 형식
-
생성된 객체의 (heap에 올라감) 주소를 저장한 keyword
-
<특징)어디에서나 쓸수 있지만 객체가 생성되기전 호출되는 영역에서는 쓸수 없다. <(static 영역ㄴㄴ)
-
static 역역 안에서는 사용할 수 없다 <(인스턴스안에서만 사용가능)<편함..
-
문법)
this.변수명
this.method명();
<변수나 메소드를 쓸때 쓰게 됨.
ex)
class Test{
int i ;
public void temp(int i){
system.out.println(i);//1000
}
public static void main(String[] args){
Test t = new Test();
t.temp=1000;
s.o.p(t.i);//0
//i에 값을 넣어 준 적이 없음.
}
//1000이 나오게 고치려면 노란부분을 고쳐야 하는데,
//이렇게 고친다.
class Test{
int i ;
public void temp(int i,Test t){
system.out.println(i);//1000
t.i=i;
}
public static void main(String[] args){
Test t = new Test();
t.temp(1000, t);
s.o.p(t.i);//0->1000
}
}
-
<이걸 편하게 쓰기 위해 this가 나온것.
-
<클래스를 매개변수로 준다음에 t에 값을 넣으면 t.i에 1000이 들어가 값이 들어있는 heap부분에 저장하게 됨으로 1000이 유지된다.
-
<<<Test t라는 주소를 넣어주어야 주소를 받고 그주소의 변수에 값을 넣어주어 살아있게 된다.
<JVM에서 벌어지는 일>
|
println frame
println
[x][t.i]=>1000 |
|
class Test{
int i ;
public void temp(int i,Test t){
system.out.println(i);//1000
t.i=i;
}
public static void main(String[] args){
Test t = new Test();
t.temp(1000, t);
s.o.p(t.i);//0->1000
}}
//주소를 불러다 꽂아준다.
class Test{
int i ;
public void temp(int i){
System.out.println(i);//1000
this.i=i;//인스턴스 변수를 부르는 t로 대치가 된다
}
public static void main(String[] args){
Test2 t = new Test2();
t.temp(1000);
System.out.println(t.i);//0
}}
//this를 keyword로 사용한 버전
//두개가 같다. |
|
println frame
x][i참조 |
| |
|
t][10번지 주소]
i][1000
(temp frame) |
| |
클래스(static변수 잡고)->메인(Test t=new Test();)
->temp->int i, test T >temp는 멈추고 println 프레임
int x는 x는 실행되기 바로 직전인 i를 넣어주게 된다.
그리고 사라짐
->temp로 다시 돌아와 마저 실행)
t.i=i;
i=10번지 가 됨
heap i=stack i // i][1000
->temp사라지고
main으로 ->println
->사라지고 닫는중괄호 만나서 다지워지고 끝
//지역변수는 만들어 지고 지워지고 반복 |
[t][10번지 주소]
(main메소드 에있으니까 main frame) |
[i][0]->
[i][1000] | |
method(static변수 |
stack(local변수 |
heap
(instance변수 | |
JVM |
class Test{
int i ;
public void temp(int i){
system.out.println(i);//1000
this.i=i;//인스턴스 변수를 부르는? t로 대치가 된다
}
public static void main(String[] args){
Test t = new Test();
t.temp(1000);
s.o.p(t.i);//0
}
-
this는 method를 호출하는 객체의 주소로 변경되는 keyword
-
<static에서는 쓸수 없다.
*String
-
기본형 데이터형과 참조형 데이터형을 가지고 있는데,변수에 값/변수에 주소 (값을 저장하기위해 예약해둔 공간의 이름)
-
기본형 데이터형 : 값자체 저장, 정수 : byte,short,int,long/문자 : char / 실수 : float,double / 불린 : boolean
-
stack영역에 [i][10]
-
참조형 데이터형 : 주소 저장 / class, 문자열, 배열 / (class: 참조형 데이터형이며, 사용자정의 데이터형) 보통 heap의 주소를 저장하는데 new가 생성해줌.
-
상수는 리터널에 저장하고 i에 저장되었다면
-
test t= new Test(); 로 heap의 주소가 담김 =>new 를 사용하여야 함 <<객체화>>
-
클래스는 안에 변수와 메소드를 갖는데, 변수는 인스턴스 변수 스테틱변수와 메소드는 생성자, 인스턴스 메소드와, 스테틱 메소드를 갖는다. method= 일 <method도 잘 보아야 , 생성자도 잘 보고~~
*문자열
-
"로 묶여 있는 여러 글자들
-
문자열은 문자열 저장소라는 literal에 생성 <<절대 같은 문자열이 생성 되지 않는다.
-
같은 문자열은 하나만 생성되고, 그 시작 주소를 사용하게 된다.
-
문자열로 저장하고 사용하기위한 class로 java.lang package에 String 제공한다.
-
String class에서 제공하는 모든 method를 사용할수 있다.
-
<문자열과 String는 다르다. String는 class 별명을 붙여 쓰기 편하게 만든것/
-
<가독성 향상하기 위함..
-
ex)
-
String address = "서울시 강남구"
-
class != String
-
int와 정수상수10이 다른것처럼.
*String class
-
참조형 데이터형
-
문자열 저장소에 주소를 저장할 수 있는 데이터 형
-
기본형 형식과 참조형 형식 2가지로 사용 가능.
-
기본형 형식 사용) (new 쓰지 않는다.)
-
String str = "ABC";
-
//<String은 제일 속도가 느린 클래스
-
참조형 형식 사용) (new 사용)
-
String str = new String("ABC");
-
<C에서는 연산자 오버로딩으로 가능하나 java는 안됨.
-
<공통으로는 문자열 저장소의 주소를 저장했다는게 공통점.
-
<String에서 제공하는 method는 다쓸수 있다.
-
== vs equals)
-
객체 ==)
-
<값이 같은지
-
<주소, 번지가 같은지 물어본다. (주소는 유일~!~!)
-
==을 사용하면 주소가 같은지 비교~!~!
-
String s= "ABC";//기본 형식
-
if (s=="ABC"){}else{
-
}//s=="ABC" 주소가 같다.
-
-
String s=new String("ABC");
-
-
if (s=="ABC"){}else{
-
}//다르다.
-
//같은 문자열일지라도 ==비교 불가
-
stack heap 문자열 저장소로 나누어 저장.
-
<기본형으로 만들어 졌는데,,문자열이 어디서 시작했는지 보기 어렵. 100프로
-
기본형 형식으로 만들면 같은 문자열 비교가 가능하지만 참조형 형식으로 만들면 heap과 stack의 주소를 비교하게 되므로 비교를 할 수 없음
-
String str = new String();
-
면 str은 지역변수로 Stack에 만들어지고 new 니까 heap에 만들어짐. heap은 주소인 10을 갖고 stack의 str은 heap의 주소인100을 가짐.
-
=>기본형 형식으로 만들면 같은 문자열인지 비교 가능하지만 참조형 혁식으로 만들면 같은 문자열인지 비교할 수 없다.
-
equals method(overloading의 대표적메소드)를 사용하면 객체내의 주소를 비교하는 기능을 수행함으로 기본형이나 참조형 형식모두 같은지에 대한 비교를 수행 할 수 있다.
반응형