배열 복사 메서드

System.arrayCopy(src, srcPos, dest, destPos, length)

Object src : 원본 소스

int srcPos : 원본 소스에서 복사를 시작할 위치

Object dest : 복사하려는 대상

int destPos : 복사하는 대상에서의 시작할 위치

int length : 얼마만큼 복사할지

e.g.

System.arraycopy(library, 0, copyLibrary, 0, 5);
// library 배열의 0번째 요소부터 복사해서 copyLibrary 배열의 0번째 부터 5개를 붙여넣기

 

얕은 복사(Shallow Copy)

객체 주소만 복사되어 한쪽 배열의 요소를 수정하면 같이 수정 된다.

즉, 두 배열이 같은 객체를 가리킨다

public class AquariumCopyTest {
    public static void main(String[] args) {
        Aquarium[] fishTank = new Aquarium[3];
        Aquarium[] copyFishTank = new Aquarium[3];

        fishTank[0] = new Aquarium("betta", 1);
        fishTank[1] = new Aquarium("guppy", 5);
        fishTank[2] = new Aquarium("otocinclus", 2);

        System.arraycopy(fishTank, 0, copyFishTank, 0, 3);

        System.out.println("====copy fish tank====");
        for (Aquarium fish : copyFishTank){
            fish.showInfo();
        }

        fishTank[0].setFishName("goldfish");
        fishTank[0].setFishCount(3);

        System.out.println("====fish tank====");
        for(Aquarium fish : fishTank){
            fish.showInfo();
        }

        System.out.println("====copy fish tank====");
        for (Aquarium fish : copyFishTank){
            fish.showInfo();
        }
    }
}

 

깊은 복사(Deep Copy)

각각의 객체를 생성하고

그 객체의 값을 복사하여 배열이 서로 다른 객체를 가리키도록 한다.

public class AquariumCopyTest {
    public static void main(String[] args) {
        Aquarium[] fishTank = new Aquarium[3];
        Aquarium[] copyFishTank = new Aquarium[3];

        fishTank[0] = new Aquarium("betta", 1);
        fishTank[1] = new Aquarium("guppy", 5);
        fishTank[2] = new Aquarium("otocinclus", 2);

        // 이렇게 따로 만들어야 한다.
        copyFishTank[0] = new Aquarium();
        copyFishTank[1] = new Aquarium();
        copyFishTank[2] = new Aquarium();

        for (int i=0; i<fishTank.length; i++){
            copyFishTank[i].setFishName(fishTank[i].getFishName());
            copyFishTank[i].setFishCount(fishTank[i].getFishCount());
        }

        fishTank[0].setFishName("goldfish");
        fishTank[0].setFishCount(3);

        System.out.println("====fish tank====");
        for(Aquarium fish : fishTank){
            fish.showInfo();
        }

        System.out.println("====copy fish tank====");
        for (Aquarium fish : copyFishTank){
            fish.showInfo();
        }
    }
}

 

 

 

 

SCE(Short-Circuit Evaluation, 단락 회로 평가)이란 최단거리 연산을 말한다.

자바는 SCE연산을 수행하는데 아래의 예시를 보면 쉽게 알 수 있다.

public class SCE{
	public static void main(String[] args){
		
		int a = 10;
		int b = 1;
		
		System.out.println("변수 a, b 출력");
		System.out.println("a : " + a);
		System.out.println("b : " + b);
		
		System.out.println("\\n논리 연산자 &&");
		boolean value = ((a = a + 10 ) < 10) && ( ( b = b + 2 ) < 10);
		
 		System.out.println(value);
		System.out.println("a : " + a);
		System.out.println("b : " + b);
		
		System.out.println("\\n논리 연산자 ||");
		value = ((a = a + 10 ) < 10) || ( ( b = b + 2 ) < 10);

		System.out.println(value);
		System.out.println("a : " + a);
		System.out.println("b : " + b);
	}
}
//--==>> 출력 결과
/*
false
20
1
true
30
3
*/

논리 곱 연산자(&&)를 실행 했을 경우는 둘 중에 하나만이라도 false 이면 결과는 언제나 false 이다.

((a = a + 10 ) < 10) 이 연산을 수행한 결과 false 이기에 이후의 연산은 수행하지 않는 것이다.

그래서 b는 연산이 수행되지 않고 여전히 1을 담고 있는 것이다.

 

만약 논리 합 연산자(||)의 경우 

value = ( (a = a + 10) > 10 ) || ( (i = i + 2) < 10 );

이 구문이 실행되었다면, 앞의 항의 결과에서 true가 나오기에 뒤 항의 결과를 평가할 필요가 없기에 그래도 true를 출력하고 i 값은 여전히 1이다.

 

 

정리하자면,

논리 곱(&&)은 두 항의 결과가 모두 true 일때만 true 이고 앞의 항의 결과가 false이면 뒤 항의 결과는 평가하지 않는다.

논리 합(||)은 두 항의 결과가 모두 false 일때만 false 이고 앞의 항의 결과가 true이면 뒤 항의 결과를 평가하지 않는다.

 

 

'Java > Java' 카테고리의 다른 글

자바 객체 배열 복사  (0) 2022.07.29
상속(Java)  (0) 2022.04.27
static 제어자 (Java)  (0) 2022.04.25
DBConn(DB연동을 위한 클래스 생성)  (0) 2022.04.23
클래스 접근 지정자와 생성자 접근 지정자(java)  (0) 2022.04.20

http://www.yes24.com/Product/Goods/103389317

 

Do it! 자바 완전 정복 - YES24

이 책은 ‘이제 막 프로그래밍에 입문한 사람’에게 꼭 필요한 기본기부터 ‘찐개발자’라면 꼭 알아야 할 내용까지 국내 집필서 중 가장 많은 도해와 그림을 이용해 설명한다. 특히 프로그래

www.yes24.com

Do it! 자바 완전 정복 책을 공부하며 요약・정리한 내용입니다.


 

상속

부모 클래스의 필드, 이너클래스, 메서드를 자식 클래스 내부에 포함시킴

 

부모클래스 ← 자식클래스

class 자식클래스 extends 부모클래스 {
		...
}

부모 클래스는 자식 클래스의 공통적 특징을 모아 구성한 클래스 이다.

자식클래스는 부모 클래스의 모든 멤버(필드, 이너클래스, 메서드)를 내려받고 자식클래스에서 추가 필드와 메서드를 구성하면 된다.

부모 클래스에서 자식클래스로 갈수록 더 많은 특징과 기능이 구체화 되므로 범위가 좁아진다.

클래스는 다중 상속(부모 클래스가 2개 이상)이 불가능하다.

 

참고로 UML로 상속을 표시할때는 화살표가 부모 클래스 쪽으로 향함

e.g. 부모클래스 ← 자식클래스

 

상속의 장점

  1. 코드의 중복성 제거
  2. 다형적 표현 가능
  • 1개의 객체를 여러 가지 모양으로 표현할 수 있다.
Animal a1 = new Dog();
Animal a2 = new Dragon();
Animal a3 = new Bear();

 

다중 상속을 허용하지 않는 이유

만일 다중 상속을 허용하면 모호성(ambiguous)이 발생한다.

e.g.


class A에 data는 3이고

class B의 data가 4일때

만약 class C extends A, B 이렇다면 C의 data의 값에는 모호성이 발생한다.


자식클래스가 많은 것은 다중 상속이 아니다.

 

생성자의 상속 여부

생성자는 자식 클래스로 상속되지 않는다.

e.g.

class A {
	A() {}
}

class B extends A {
	A() {} // X
}

클래스 내부에는 필드, 메서드, 생성자, 이너 클래스만 올 수 있다.

그래서 예시의 B클래스의 A(){} 는 B클래스와 이름이 달라 생성자도 아니고 리턴타입도 없어 메서드도 아니다.

즉 오류가 발생한다.

 

 


http://www.yes24.com/Product/Goods/103389317

 

Do it! 자바 완전 정복 - YES24

이 책은 ‘이제 막 프로그래밍에 입문한 사람’에게 꼭 필요한 기본기부터 ‘찐개발자’라면 꼭 알아야 할 내용까지 국내 집필서 중 가장 많은 도해와 그림을 이용해 설명한다. 특히 프로그래

www.yes24.com

Do it! 자바 완전 정복 책을 공부하며 요약・정리한 내용입니다.


인스턴스 멤버(instance member)

앞에 static이 붙어 있지 않으며 클래스의 객체를 생성해야 다른 클래스에서 사용 가능

 

정적 멤버(static member)

앞에 static이 붙어 있으며 다른 클래스에서 객체 생성 없이 클래스명.멤버명 으로 바로 사용 가능

 

인스턴스 필드와 정적 필드

인스턴스 필드

class A {
	int x = 3;       // 인스턴스 필드
}

public Class B {
	public static void main(String[] args) {
		// 인스턴스 필드 활용 : 객체 생성후 사용
		A a = new A();
		System.out.println(a.x);
	}
}
//--==>> 3

인스턴스 x는 객체 내부에 저장 공간이 생성되기에 반드시 객체를 먼저 생성해야 한다. 또한 저장 공간이 힙 메모리에 위치하므로 해당 저장 공간에 값을 읽기 위해 참조 변수명을 사용해야 한다.

 

정적 필드

class A {
	static int y = 4;      // 정적 필드
}

public class B {
  public static void main(String[] args) {
		System.out.println(A.y);
		// 정적 필드 활용 : 객체 생성 없이 클래스 명으로 사용
    
		A a = new A();
		System.out.println(a.y);
		// 객체 생성을 한 이후 사용할 수 있지만
		// 이렇게 사용하면 적정 필드임을 나타내기 어려워서 권장하지 않음
	}
}

정적 필드는 클래스 내부에 저장 공간을 지니고 있다. 즉 객체가 생성되기 전에 먼저 생성 그러니까 객체 생성 없이 바로 사용할 수 있다.

또한 클래스 내부에서 클래스 내부에 저장되기 때문에 객체 간 공유하는 성질이 있다.

아래 예시를 보면 쉽게 이해할 수 있다.

e.g.

class A{
    int x = 3;           //인스턴스 필드
    static int y = 4;    //정적 필드
}

public class B {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
	
				// 인스턴스 필드
        a1.x = 30;
        a2.x = 300;
        System.out.println("a1.x : " + a1.x);
        System.out.println("a2.x : " + a2.x);

				// 정적 필드
        a1.y = 40;
        a2.y = 400;
        System.out.println("a1.y : " + a1.y);
        System.out.println("a2.y : " + a2.y);
    }
}
//--==>>
/*
a1.x : 30
a2.x : 300
a1.y : 400
a2.y : 400
*/

 

인스턴스 메서드와 정적 메서드

인스턴스 메서드

class A {
	void inMethod () {       //인스턴스 메서드
		System.out.println("Instance Method");
	}
}

public class B {
	public static void main(String[] args) {
		// 인스턴스 메서드 활용 : 객체 생성후 사용
		A a = new A();
		a.inMethod();
	}
}
//--==>> Instance Method

정적 메서드

class A {
	void stMethod() {        // 정적 메서드
		System.out.println("Static Method");
	}
}

public class B {
	public static void main(String[] args) {
		//정적 메서드 활용 : 객체 생성 없이 클래스 명으로 사용
		A.stMethod();
		
		A a = new A();
		a.stMethod();
		// 객체 생성을 한 이후 사용할 수 있지만
		// 권장하지 않음
	}
}
//--==>> Static Method

정적 메서드 내에서는 정적 필드, 정적 메서드만 사용 가능!!

인스턴스 필드나 인스턴스 메서드는 사용 불가!!

왜냐하면 인스턴스 필드나 인스턴스 메서드는 객체를 생성한 이후에 사용 가능하다.

하지만 객체 생성 이전에 실행하려는 정적 메서드 내부에는 객체 생성하기 전에 사용할 수 있는 요소(정적 멤버)들로만 구성되어야 하기 때문이다.

이는 정적 메서드 내부에서는 클래스 자신의 객체를 가리키는 this 키워드를 사용할 수 없다는 것 또한 의미한다.

 

 

 

DB 연동을 편리하게 하기위해 Class로 선언

 

DBConn클래스

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConn {
    // Connection 타입의 전역변수 dbConn 선언
    private static Connection dbConn;

    // 메소드 정의
    public static Connection getConnection() throws ClassNotFoundException, SQLException {
        // 한 번 연결된 객체를 계속 사용
        // 즉, 연결되지 않은 경우에만 연결을 시도하겠다는 의미
        // → 싱글톤(디자인 패턴)
        if (dbConn == null) {
            String url = "jdbc:oracle:thin:@localhost:1521:xe";
            //-- 『localhost』 는 오라클 서버의 ip 주소를 기재하는 부분(로컬아니면 ip번호 입력)
            //	 『1521』 은 오라클 리스너 Port Number(다른 포트번호 할 수 도 있다)
            //	  『xe』 는 오라클 SID(Express Edition 의 SID는 xe)
            String user = "scott";
            //-- 오라클 사용자 계정 이름
            String pwd = "tiger";
            //-- 오라클 사용자 계정 암호

            Class.forName("oracle.jdbc.driver.OracleDriver");
            //-- OrcleDriver 클래스에 대한 객체 생성
            dbConn = DriverManager.getConnection(url, user, pwd);
            //-- 오라클 서버 실제 연결
            //	 인자값(매개변수)은 오라클주소, 계정명, 패스워드

        }
        return dbConn;
        //-- 구성된 연결 객체 반환
    }

    // getConnection() 메소드의 오버로딩
    public static Connection getConnection(String url, String user, String pwd) throws ClassNotFoundException, SQLException {
        if (dbConn == null) {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            dbConn = DriverManager.getConnection(url, user, pwd);
        }

        return dbConn;
    }

    // 메소드 정의 → 연결 종료
    public static void close() throws SQLException {
        // dbConn 변수(멤버 변수)는
        // Database 가 연결된 상태일 경우 Connection을 갖는다.
        // 연결되지 않은 상태라면 null 인 상태
        if (dbConn != null) {
            // 연결 객체(dbConn)의 isClosed() 메소드를 통해 연결 상태 확인
            //-- 연결이 닫혀있는 경우 true 반환
            //	 연결이 닫혀있지 않은 경우 false 반환
            if (!dbConn.isClosed()) {
                dbConn.close();
                //-- 연결 객체의 close() 메소드 호출을 통해 연결 종료~!!!
            }
        }

        dbConn = null;
        //-- 연결 객체 초기화
    }
}

 

 

같은 기능의 클래스를 try~catch로 처리

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConn{
	private static Connection dbConn;
	
	public static Connection getConnection(){
		if (dbConn == null){
			try{
				String url = "jdbc:oracle:thin:@localhost:1521:xe";
				String user = "scott";
				String pwd = "tiger";
				
				Class.forName("oracle.jdbc.driver.OracleDriver");
				dbConn = DriverManager.getConnection(url, user, pwd);
				
			} catch (Exception e){
				System.out.println(e.toString());
			}
		}
		
		return dbConn;
	}
	
	public static Connection getConnection(String url, String user, String pwd){
		if (dbConn == null){
			try{
				Class.forName("oracle.jdbc.driver.OracleDriver");
				dbConn = DriverManager.getConnection(url, user, pwd);
				
			} catch (Exception e){
				System.out.println(e.toString());
			}
		}
		
		return dbConn;
	}
	
	public static void close(){
		if (dbConn != null){
			try{
				if (!dbConn.isClosed())
					dbConn.close();
				
			} catch (Exception e){
				System.out.println(e.toString());
			}
		}
		dbConn = null;
	}	
}

 

 

 

 

 

 


https://www.instagram.com/p/Ca1UMPlJ2mN/?utm_source=ig_web_copy_link

부족하거나 잘못된 내용이 있을 경우 댓글 달아주시면 감사하겠습니다.

이 글에 부족한 부분이 존재할 경우 추후에 수정될 수 있습니다.


 


http://www.yes24.com/Product/Goods/103389317

 

Do it! 자바 완전 정복 - YES24

이 책은 ‘이제 막 프로그래밍에 입문한 사람’에게 꼭 필요한 기본기부터 ‘찐개발자’라면 꼭 알아야 할 내용까지 국내 집필서 중 가장 많은 도해와 그림을 이용해 설명한다. 특히 프로그래

www.yes24.com

Do it! 자바 완전 정복 책을 공부하며 요약・정리한 내용입니다.


 

접근 지정자와 사용 가능 범위

public 동일 패키지의 모든 클래스 + 다른 패키지의 모든 클래스에서 사용 가능
protected 동일 패키지의 모든 클래스 + 다른 패키지의 자식 클래스에서 사용 가능
default 동일 패키지의 모든 클래스에서 사용 가능
private 동일 클래스에서 사용 가능

 

클래스에서 생성자가 없는 경우 컴파일러는 기본 생성자를 자동으로 추가한다. 이 과정에 자동으로 추가되는 생성자는 그 클래스의 접근 지정와 동일한 접근 지정자로 정해진다.

 

예를 들어 public클래스에서 자동으로 추가되는 생성자도 public이고, default 클래스에서 자동으로 추가되는 생성자는 default가 되는 것이다.

 

e.g.

package temp.test1;

// public 클래스
public class A {
	//기본 생성자 자동으로 생성(public)
}
package temp.test1;

// default 클래스
class B {
	// 기본 생성자 자동으로 생성(default)
}
package temp.test1;

//public 클래스
class C {
	C() {
		//default 생성자 직접 생성
	}
}
package temp.test2;

import temp.test1.A;
//import temp.test2.B;
import temp.test1.C;

public class Modifier {
	public static void main(String[] args) {
		A a = new A();
		
		// B b = new B();
		// 클래스 B는 import 할 수 없으므로 선언, 호출 불가
		
		// C c = new C();
		// 클래스 C는 import 가능해서 선언은 가능하지만
		// default생성자여서 호출은 불가능
	}
}

 

 

 


https://www.instagram.com/p/CaRRlZwPc4a/?utm_source=ig_web_copy_link

부족하거나 잘못된 내용이 있을 경우 댓글 달아주시면 감사하겠습니다.

이 글에 부족한 부분이 존재할 경우 추후에 수정될 수 있습니다.