본문 바로가기
Backend

05월 30일 목 | OOP 11 - JAVA의 this(), Static, Final, String

by 구라미 2019. 5. 30.

9. 객체지향 프로그래밍

This ()

생성자함수 추가, 생성자함수를 호출

자바에서 this는 '객체, 자기 자신'을 나타낸다.

this.멤버변수, this.멤버메소드, this()와 같이 사용하며 생성자를 호출한다.

 

주로 3가지 형태로 사용되고 있다.

 

1. 클래스의 속성과 생성자/메소드의 매개변수의 이름이 같은 경우

- 클래스의 속성을 사용할 때 this키워드를 붙인다.

 

2. 클래스에 오버로딩된 다른 생성자를 호출할 때

- 생성자의 최상단에 사용되어야 한다.

 

3. 객체 자신의 참조값을 전달하고 싶을 때

 

package oop0530;

import oop0529.School; //어제 만든 School 클래스 끌어오기


public class Test01_This {

	public static void main(String[] args) {
		
		School sch = new School(); //import가 없으면 에러
		
	}//main end
}//class end

 

지난 번 배웠던 접근제한자 내용이다.

1) School 클래스의 접근제어 : public

import로 oop0529패키지 내에 있는 School 클래스를 불러온 것이다.

School 클래스의 접근제어가 public인 경우 접근가능하다.

 

2) School 클래스의 접근제어 : package

같은 package안에 있는게 아니라면 접근 불가능하다.

 

3) School 클래스의 접근제어 : 없을때

에러가 생기며 접근 불가능하다.

 

import oop0529.* <-oop0529패키지의 모든 클래스를 불러오겠다라는 뜻.

 

생성자는 클래스 이름과 같다.

생성자메소드도 불러다 쓴다. 생성자메소드가 생성자메소드를 호출할 수 있다.

그러나 이름을 불러다 쓰지 말고 내가 나를 부르는 것이므로 this를 사용해서 호출

public Sungjuk(){
	//생성자함수가 생성자함수를 호출할 수 있다.
	this("박영선"); //에러 없음
	Sungjuk("박영선"); //에러	
}

 

생성자메소드를 호출할 때는 호출하는 첫 줄에서 해야한다.

public Sungjuk(int kor, int eng, int mat){
	this();//생성자가 자신의 생성자함수를 호출할 때 쓴다.
	this.kor = kor;
	this.eng = eng;
	this.mat = mat;
}
	
public Sungjuk(int avg){
	this.avg = avg;
	//this(10,20,30); // 에러: 생성자함수를 호출할 때는 호출하는 첫 줄에서 한다. 
}    

 

생성자메소드에서는 일반메소드를 호출할 수 있다.

일반메소드에서 this 쓸 수 없다.

public Sungjuk(int kor, int eng, int mat){
	this();//생성자가 자신의 생성자함수를 호출할 때 쓴다.
	this.kor = kor;
	this.eng = eng;
	this.mat = mat;
}
	
public Sungjuk(int avg){
	this.avg = avg;
	//this(10,20,30); // 에러: 생성자함수를 호출할 때는호출하는 첫 줄에서 한다.
	disp();
}
	
public void disp(){
	this(85); //에러
}

this라는 명령어는 생성자메소드에서만 쓰는 것이다. 자기들끼리만

 


 

Static

객체마다 데이터를 가지고 있는데 , 이를 공유해야할 상황에 static을 사용한다.

여러 객체의 메소드들이 동시에 접근, 수정할 수 있는 전역변수 같은 느낌이다.

static키워드를 사용한 변수를 클래스 변수라고 한다. 즉 객체가 아닌 클래스변수이기 때문에 new로 객체 생성하지 않아도 사용가능.

 

stack 공간 -> 계속 리셋

static 공간 -> countinue

Static 변수, Static 메소드

메모리 생성도 1번, 소멸도 1번 -> 한번 생성되면 지속

클래스변수는 JVM Runtime Data Area에서 Method Area에 들어간다. 여기서 클래스는 Method Area에 객체는 Heap Area에

들어간다. 따라서 static변수, static메소드는 Method Area에 들어가기 때문에 모든 객체에서 가져다 사용할 수 있다.

new연산자를 이용해서 별도의 객체생성 없이 사용가능하다.

 

1. 클래스를 설계할 시, 멤버변수 중 모든 인스턴스에 공통적으로 사용해야하는 것에 static 키워드를 붙인다.

-인스턴스를 생성하면, 각 인스턴스들은 서로 독립적이기에 서로 다른 값을 유지한다.

2. static 키워드가 붙은 멤버변수나 메소드는 인스턴스(객체화)하지 않아도 사용할 수 있다.

-static 변수와 static메소드는 클래스가 메모리에 올라갈 때 자동으로 생성된다.

3. static이 붙은 메소드에서는 인스턴스 변수(static이 아닌것)를 사용할 수 없다.

4. 메소드 내에서 인스턴스 변수를 사용하지 않는다면 static을 사용하는 것을 고려한다.

-메소드를 만들면서 인스턴스 변수가 필요하다면 static을 사용할 수 없지만,

인스턴스 변수가 필요없다면 static을 사용한다. 메소드 호출시간이 짧고 효율성이 좋기 때문에.

 

static메소드는 객체가 생성되지 않는 상태에서 호출되는 메소드이다.

static메소드 안에서는 static변수와 지역변수만 사용할 수 잇다.

static메소드 안에서는 인스턴스메소드를 호출하지 못한다.

static메소는 this키워드를 사용할 수 없다. this를 참조할 인스턴스가 없기 때문이다.

 

 

1) static의 특징을 적용하지 않은 경우

package oop0530;

class Sawon {
	
	//멤버변수 field
	String saNum;  //사원번호
	String name;
	int pay;       //급여
	
	//Static 변수
	static String COMPANY="(주)솔데스크"; //static 변수는 구분을 위해 이탤릭체로 나온다.
	static int Sudang=10;
	static double TAX=0.03;
	
	//Static 메소드
	static void line(){
		System.out.println("-------------------------------------");
	}
	
	Sawon(){}
	Sawon(String saNum, String name, int pay){
		this.saNum = saNum;
		this.name = name;
		this.pay = pay;
	}	
	
}//class end


public class Test03_Static {

	public static void main(String[] args) {
		//static
		Sawon one = new Sawon("1001","손흥민",100);
		//총 지급액 : (급여*세금)+수당
		int total = (int)(one.pay-(one.pay*one.TAX))+one.Sudang;
		
		//출력
		System.out.println(one.COMPANY);
		System.out.println("사원번호: "+one.saNum);
		System.out.println("이름: "+one.name);
		System.out.println("총 지급액: "+total);
		one.line();		
		
		
	}//main end
}//class end

//(주)솔데스크
//사원번호: 1001
//이름: 손흥민
//총 지급액: 107
//-------------------------------------


 

2) Static 특징을 적용한 경우

static 변수와 메소드는 이미 static 메모리에 값이 상주해 있기 때문에 
별도의 객체생성을 하지 않고도 직접 접근할 수 있다.
Static 접근방법: 클래스명.static변수, 클래스명.static메소드()

Sawon two = new Sawon("1002","박지성",200);
int total = (int)(two.pay-(two.pay*two.TAX))+two.Sudang;		
		
System.out.println(two.COMPANY);
System.out.println("사원번호: "+two.saNum);
System.out.println("이름: "+two.name);
System.out.println("총 지급액: "+total);
Sawon.line();

▶ 풀이

새 사원 객체 two를 만들고 two.COMPANY로 static변수 COMPANY를 출력했다.

 

 

3) Static 변수의 연산

static 변수도 연산이 가능하다.

System.out.println(kim.Sudang); //10
System.out.println(lee.Sudang); //10
		
kim.Sudang=kim.Sudang+1;
System.out.println(kim.Sudang); //11

lee.Sudang=lee.Sudang+1;
System.out.println(lee.Sudang); //12
System.out.println(kim.Sudang); //12

Sawon.Sudang=Sawon.Sudang+1;
System.out.println(Sawon.Sudang); //13

변수가 연산이 계속되어 값이 누적 된다.

static은 딱 하나밖에 안생기기 때문에 메모리 공간을 같이 쓰게된다. 있는 것을 재활용

공유공간의 개념. 그래서 연산하면 값이 동일한 데서 연산됨.

특정한 값을 공유해야할 때 static변수를 쓴다.

//static 변수
System.out.println(Math.PI);
//static 메소드
System.out.println(Math.abs(-3));
	
System.out.println(Integer.parseInt("5"));

 


Final

final은 상수를 표현하기 위한 예약어이다.

변수, 함수, 클래스 확장 못하게 한 것.

변수: 변수의 상수화. 주로 static과 같이 사용한다.

클래스: 누군가의 부모클래스가 될 수 없다. 자식을 둘 수 없음. 상속받기 상속하기 둘 다 불가. //종단클래스

메소드: 더 이상 오버라이드(override, 재정의) 할 수 없다.

final과 abstract를 함께 사용할 수 없다.

 

1) final 변수

- 상수라고 할 수 있다. 상수처럼 사용할 변수 앞에 final을 붙인다.

- 변수 선언과 동시에 초기화하며 수정이 불가하다.

- 오직 get만 가능하다.

//final 변수
		
//일반변수, 값을 갱신가능하다.
int a = 3;
System.out.println(a); //3
a=5;
System.out.println(a); //5
		
//final 변수, 값을 갱신 불가능. 선언한 순간 마지막 고정불변값. 상수
final int b = 2;
System.out.println(b); //2
b=4; //에러난다.

final이라는 말을 앞에 붙여서 변수를 선언하면 상수. 고정불변한 값이 된다.

변경이 불가하게 제약을 걸어둔 값이다.

 

2) final 클래스

- 종단클래스라고도 한다.

- 상속이 불가능하다.

- subclass를 생성할 수 없다.

final class Animal {	
}
class Elephant extends Animal{ //에러메시지가 뜬다. final 클래스는 상속이 불가하다.
}

 

3) final 메소드

- 오버라이딩이 불가하다.

- 상속 받은 그대로 사용해야 한다.

//3)final 메소드
class Fruit {
	void view(){}
	final void disp(){}
}

class Apple extends Fruit { //Fruit가 종단클래스는 아니라서 상속은 된다.
	//@override//재정의(리폼)	
	void view(){}
    //ctrl+space 했을 때 final disp는 뜨지 않는다.
}

final void disp는 final 메소드이기 때문에 불러올 수 없다.

 


String

String은 문자열을 표현하는, 자바에서 가장 많이 사용하는 클래스이다.

String은 원시타입(기본형)처럼 사용되지만 사실 참조형 클래스객체이다. 

String객체는 하나 생성되면, 그 값은 길어지거나 줄어들 수 없는 변경불능객체이다.

하지만 String 클래스의 메소드를 사용하여 String 결과를 수정한 것을 새로운 String 객체로 반환할 수 있다.

 

String 생성자

자바의 문자열은 java.lang패키지의 String클래스의 인스턴스로 관리된다. 소스상의 문자열 리터럴은 String객체로 자동생성되지만, String 클래스의 다양한 생성자를 통해 직접 String객체를 생성할 수도 있다.

 

문자열을 만드는 두 가지 방법이 존재한다.

1. 문자열 리터럴을 지정하는 방법

*상수 : 변하지 않는 변수

*리터럴: 변수 및 상수에 저장되는 값 자체 (이것이 메모리에 저장된다.)

정수 리터럴 - 10,1,100 등

실수 리터럴 - 1.2,35.5 등

문자 리터럴 - "안녕하세요" ,"Hello" 등 

실제로 저장되는 값을 의미한다.

 

2. String 클래스의 생성자를 사용해서 만드는 방법.

 

 

String 메소드

String은 문자열의 추출, 비교, 찾기, 분리, 변환 등과 같은 다양한 메소드를 갖고 있다.

그 중에서도 자주 사용되는 메소드들이 있다.

 

-length(), charAt()

 

length메소드는 String의 길이를 리턴한다. 리턴형은 int 이다.

charAt메소드는 n번째 문자 출력한다. 리턴형은 char이다. 

String name = new String("soldesk");
String str = "Gone with the Wind";
		
//글자갯수
System.out.println(str.length()); //18 , str의 글자갯수 출력
		
//0번째 글자 'G' char형
System.out.println(str.charAt(0));//G, n번째 글자를 출력
		
//마지막 글자 'd' char형
System.out.println(str.charAt(17));//d, 마지막 글자를 출력
		
System.out.println(str.length()-1); //17
System.out.println(str.charAt(str.length()-1)); //d

맨 앞번째 :0

맨 뒷번호: str.length로 나온값 - 1 

수가 엄청 커질 수도 있으므로 숫자보단 str.charAt((str.length)()-1) 표현사용

 

-indexOf

indexOf 메소드는 해당 문자가 시작되는 인덱스를 int로 리턴한다.

해당 문자가 존재하지 않는다면 -1을 리턴한다.

//글자로 순번 알아내기 
System.out.println(str.indexOf("G"));
		
//중복되는 문자열이면 처음 문자열의 인덱스 반환
System.out.println(str.indexOf("e")); //우선 3번째를 찾아주는데, 뒤에 e가 하나 더있다.
System.out.println(str.indexOf("k")); //없는 값을 입력했을 때 -1 반환

문자열 중 임의의 글자가 없다면 -1과 같다 또는 0보다 작다. (이런 식의 조건문을 사용해서 코딩함)

 

-toLowerCase(), toUpperCase()

toLowerCase는 전부 소문자로, toUpperCase는 전부 대문자로 변환해주는 메소드이다. 

System.out.println(str.toLowerCase()); //전부 소문자로 변환
System.out.println(str.toUpperCase()); //전부 대문자로 변환

//결과값
//gone with the wind
//GONE WITH THE WIND

 

-replace(예전, 지금)

replace는 문자를 교체해주는 메소드이다.

System.out.println(str.replace('n','N')); //소문자 n을 모두 대문자 N으로 
System.out.println(str.replace('e','b')); //소문자 n을 모두 대문자 N으로

//결과값
//GoNe with the WiNd
//Gonb with thb Wind

 

-isEmpty()

문자열이 공백인지 아닌지 물어보는 메소드로 boolean값 리턴한다.

if(str.length()==0){
	//str이 빈문자열이다.
	System.out.println("빈 문자열입니다.");
}else{
	System.out.println("빈 문자열이 아닙니다.");
	}
		
//위의 조건문을 isEmpty()함수로 바꾸시오		
System.out.println(str.isEmpty());
		
if(str.isEmpty()){
	System.out.println("빈 문자열입니다.");
}else{
	System.out.println("빈 문자열이 아닙니다.");
}

 

-startWith(), endsWith()

시작하는 문자열, 끝나는 문자열이 맞나 판별해주는 메소드

startWiht은 앞에서부터 문자열 비교, endsWith은 뒤에서부터 문자열 비교해준다.

boolean형으로 리턴한다.

System.out.println(str.startsWith("Gone")); //true
System.out.println(str.endsWith("Wind"));   //true
System.out.println(str.startsWith("Done")); //false
System.out.println(str.endsWith("fire"));   //false

-equals()

문자열의 내용을 비교해준다.

문자열의 내용을 비교할 때 =(같다)연산자 쓰지 말고 이 메소드를 사용해서 비교해야한다.

//문자열 내용비교
System.out.println("sky".equals("hi")); //false

 

-substring()

원하는 문자열을 일부만 가져온다.

.substring(int beginindex, int endindext)

슬라이싱하는 개념인데 인덱스는 배열과 같이 0부터 시작하며 두번째 인자의 -1까지 출력해준다.

.substring(index)

만약 위 처럼 두번째 인자가 없을 경우는 index부터 문자열 끝까지 리턴한다.

 

★★★★★정말 많이 쓰이는 기능이므로 꼭 기억해두기★★★★★

//ith the Wind - 6번째글자부터 마지막까지 다 출력
System.out.println(str.substring(6));
		
//ith - 6번째 글자부터 12-1번째글자까지 출력
System.out.println(str.substring(6,12));

//첫번째 글자 출력해보기
System.out.println(str.substring(0,1)); 
//꼬릿말 공간확보해야해서 0,0가 아니라 0,1이어야함. 출력 String형

//마지막 글자 출력해보기
System.out.println(str.substring(str.length()-1,str.length()));
System.out.println(str.substring(str.length()-1)); //이렇게 해도 된다.

//결과값
//ith the Wind
//ith th
//G
//d

문자열은 저장이될 때 꼬릿말을 저장해주는 공간이...

length 메소드 잘 이용해야한다.

 

 

-split()

규칙성이 있는 문자열에서 특정 반복점을 기준으로 문자열을 분리할 수 있다.

문자열을 parameter 기준으로 쪼개서 String형 배열로 리턴해준다.

//문자열 분리하기
String[] word = str.split(" ");
for(int i=0; i<word.length; i++){
	System.out.println(word[i]);
}

//결과값
//Gone
//with
//the
//Wind

공백을 기준으로 문자열을 분리한 결과이다.
공백, 콤마 등을 기준으로 문자열을 분리한다.

 

-trim()

문자열의 좌우 끝에 존재하는 공백을 제거할 때 사용한다.

//문자열의 좌우 끝에 존재하는 공백을 제거할 때 사용한다.
System.out.println("#"+"  s k y  "+"#");
System.out.println("#"+"  s k y  ".trim()+"#");

//결과값
//#  s k y  #
//#s k y#

 


연습문제

 

연습문제 1) 이메일 주소에 @문자 있으면 @글자 기준으로 문자열을 분리해서 출력하고

@문자가 없다면 "이메일주소 틀림" 메시지를 출력하시오.
출력결과 : 

 

내 풀이

String email= "webmaster@soldesk.com";
	
if(email.indexOf("@")!=-1){
	String[] em = email.split("@");
	for(int k =0; k<em.length; k++){
		System.out.println(em[k]);
	}		
}else{
	System.out.println("이메일주소 틀림");					
}	
		
System.out.println();

//결과값
//webmaster
//soldesk.com

▶ 풀이

1. if문으로 "@"의 인덱스가 있는지 알아낸다. indexOf("@")가 -1이 아니라면, 문자열이 @문자가 있는 것이다.

2. String 배열 em에 "@"을 기준으로 썰은 문자열을 배열의 원소로 넣는다.

3. 반복문을 만들어 em의 배열크기만큼 em의 요소를 반복해서 출력한다.

4. 위 if문의 조건이 틀리다면 "이메일주소 틀림"을 출력한다.

 

선생님 답안■

String email= "webmaster@soldesk.com";
		
int pos=email.indexOf("@"); //lastIndexOf도 있음 알아서 찾기
System.out.println(pos); //9번째에 @가 있다.
	
if(pos==-1){ //해당 문자열이 전체 문자열 중에 있나 판별
	System.out.println("이메일주소 틀림");
	} else {
				
	System.out.println("이메일주소 맞음");
	String id = email.substring(0,pos);
	String server = email.substring(pos+1);
	System.out.println(id+","+server);
}

//결과값
//이메일주소 맞음
//webmaster,soldesk.com

▶ 풀이

선생님은 indexOf와 substring을 사용하셨다.

1. int pos는 "@"가 있는 위치의 번호이다.

2. if문을 만들어 만약 pos가 -1이라면 문자열에 @가 없는 것이므로 "이메일주소 틀림"을 출력한다.

3. 그게 아니라면 "@"가 있는 것이므로 "이메일주소 맞음"을 출력한다.

4. String id에 substring 메소드로 (0,pos) 까지 문자열을 넣어주고

5. String server에 역시 같은 메소들 (pos+1)의 나머지 문자열을 넣어준다. (꼬리공간 다음부터 넣어주는 것임)

6. 문자열 콤마로 구분한 id와 server를 출력한다.

 

 

연습문제 2) 주민번호를 이용해서 아래와 같이 출력하시오

String jungmin = "1512304123456";

생년월일 : 2015년 12월 30일
성별: 여자
나이: 4
주민번호 각 숫자의 전체 합 : 37

내 풀이

//연습문제 2)
//주민번호를 이용해서 아래와 같이 출력하시오
//생년월일 : 2015년 12월 30일
//성별: 여자
//나이: 4
//주민번호 각 숫자의 전체 합 :

String jungmin = "1512304123456";
		
//생년월일
String year = 20+(jungmin.substring(0,2));
String month = jungmin.substring(2,4);
String date = jungmin.substring(4,6);
System.out.println("생년월일: "+year+"년 "+month+"월 "+date+"일 ");
		
//성별		
if((int)(jungmin.charAt(6)-48)%2==0){
	System.out.println("성별: 여자");
}else{
	System.out.println("성별: 남자");
}
		
//나이
String age = jungmin.substring(0,2);
int jmage = 2019-((Integer.parseInt(age))+2000);		
System.out.println("나이: "+jmage);
		
//주민등록번호 숫자 합
int hap = 0;
for(int a =0; a<jungmin.length(); a++){
	hap = hap + ((int)(jungmin.charAt(a))-48);
	//hap = hap + (Integer.parseInt(jungmin.charAt(a));			
}
System.out.println("주민등록번호 숫자의 합은: "+hap);

//결과값
//생년월일: 2015년 12월 30일 
//성별: 여자
//나이: 4
//주민등록번호 숫자의 합은: 37

▶ 풀이

다른 문제해결은 비교적 쉬웠는데 주민등록번호 숫자 합을 구하는 부분에서 어려웠다.

자꾸 말도 안되는 값이 도출되어서 왜그런가 했더니 숫자에도 아스키코드가 있어서 모두 합하면 숫자가 엄청 커진 것.

*주민등록번호 숫자합

1. 총 합을 넣어줄 int hap을 0으로 초기화

2. for문으로 주민번호크기 만큼 순서대로 반복

3. hap안에 주민번호문자를 형변환한 후 -48을 빼주어 아스키코드 값에서 원래 숫자로 만든다.

4. 이를 반복한것을 더해서 hap안에 넣어준다.

 

선생님 답안■

//생년월일
String year = 20+(jungmin.substring(0,2));
String month = jungmin.substring(2,4);
String date = jungmin.substring(4,6);
		
//성별코드 가져와서 정수형변환
int code = Integer.parseInt(jungmin.substring(6,7));
		
//주민번호에서 생년월일 가져오기
int myYear = Integer.parseInt(jungmin.substring(0,2));
int myMonth = Integer.parseInt(jungmin.substring(2,4));
int myDate = Integer.parseInt(jungmin.substring(4,6));
		
//태어난 년도 완성하기
switch(code){
case 1:
case 2: myYear = myYear+1900; break;
case 3:
case 4: myYear = myYear+2000; break;
}
		
//성별출력하기
String gender = "";
switch(code%2){
case 0 : gender ="여자"; break;
case 1 : gender ="남자"; break;
}
		
//나이 출력하기
int myAge = 2019-myYear;
						
System.out.println("생년월일: "+myYear+"년 "+myMonth+"월 "+myDate+"일");
System.out.println("성별: "+gender);
System.out.println("나이: "+myAge);

//주민등록번호 숫자 합
int hap = 0;
for(int a =0; a<jungmin.length(); a++){
	hap = hap+Integer.parseInt(jungmin.substring(a,a+1));
}
System.out.println("주민등록번호 숫자의 합은: "+hap);

▶ 풀이

나는 charAt을 사용해서 풀이했고 선생님은 Integer.parseInt를 사용하셨다.

코드짤 때 기능이 들어간 위치를 잘 정리해야겠다. 

선생님은 주민번호숫자를 substring(a,a+1)로 한글자씩 잘라서 가져와

참조형인 String을 Integer.parseInt로 변환하여

더해주었다.

 

연습문제 3) 파일이 이미지 파일(.gif .jpg .png)인지 확인하시오.
출력결과:
파일명: sky.png
맞으면: "파일이 전송되었습니다."
틀리면: "파일을 다시 선택해주세요"

 

내 풀이

//연습문제 3)
//파일이 이미지 파일(.gif .jpg .png)인지 확인하시오.
//출력결과)
//파일명: sky.png
//맞으면: "파일이 전송되었습니다."
//틀리면: "파일을 다시 선택해주세요"

String filename="d:/java0514/workspace/sky.png";	
			
String[] file = filename.split("/");
for(int i=0; i<file.length; i++){
	if(file[i]==file[file.length-1]){
		String img = file[i];
		System.out.println("파일명: "+img);
		if(img.endsWith(".gif")||img.endsWith(".png")||img.endsWith(".jpg")){
			System.out.println("파일이 전송되었습니다.");
		}else{
			System.out.println("파일을 다시 선택해주세요.");
		}
	}//if end
}//for end

▶ 풀이

1. 나는 split으로 "/"을 기준으로 잘라준 배열을 만들고

2. file[file.length-1]로 배열의 마지막 요소를 가져왔다. 

3. 그 요소를 String img에 넣어주었다.

4. 그 다음 endWith을 사용하여 확장자가 .gif , .png , .jpg와 일치하는지 확인하였다. 

 

선생님 답안■

//1) filename 맨 끝의 파일명을 가져오기.
System.out.println(filename.indexOf("/")); //2가 나옴.
System.out.println(filename.substring(22)); //sky.png가 나옴.
System.out.println(filename.lastIndexOf("/")); //21
		
//sky.png 잘라오기
int pos = filename.lastIndexOf("/");
filename = filename.substring(pos+1);
System.out.println(filename);
		
//2) 파일의 확장자만 가져오기.		
int dot = filename.indexOf(".");
System.out.println(dot); // .의 위치는 3
String ext = filename.substring(dot+1);
System.out.println(ext); //png만 잘라오게 되었다.
		
//3) .gif .jpg .png 중 하나인지 확인하기.
//확장자 대,소문자를 한꺼번에 처리해야하는 경우가 있음.
//확장자를 전부 소문자로 바꾼 다음 || 연산자로 확인하기.
ext = ext.toLowerCase();
if(ext.equals("png")||ext.equals("jpg")||ext.equals("gif")){ //String 비교는 equals를 많이 쓴다.
	System.out.println("파일명은: " + filename);
	System.out.println("파일이 전송되었습니다.");
}else {
	System.out.println("파일을 다시 전송해주세요.");
}

//결과값
//파일명은: sky.png
//파일이 전송되었습니다.

▶ 풀이

1. 선생님은 int pos로 마지막 "/"위치값을 담았다.

2. filename에 filename.substring(pos+1) pos이후의 문자열을 담는다.

3. int dot으로 filename에서 "."의 위치값을 담는다.

4. pos로 substring 썼던 방식으로 확장자만 잘라내서 ext에 넣어준다.

5. 확장자를 전부 소문자로 변환해준다.

6. 변환한 ext와 png, jpg, gif 중에 있는지 .equals 메소드로 확인한다.

7. 출력한다.

 

 

이메일주소 판별하는 정규표현식(자바스크립트)가 있다. 

찾아보면 나옴.

*정규표현식: 공백, 키보드기호가 네트워크 상태에서 전달이 될 때 어떤 상태로 전달되는지 정해두는 것.

댓글