엔티티 매핑 소개

  • 객체와 테이블 매핑 : @Entity, @Table
  • 필드와 컬럼 매핑 : @Column
  • 기본 키 매핑 : @Id
  • 연관관계 매핑 : @ManyToOne,@JoinColumn

객체와 테이블 매핑

@Entity

  • @Entity가 붙은 클래스는 JPA가 관리하고 , 엔티티라 한다.
  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수!!!

💡 주의

  • 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
    • 스펙 상 규정되어 있음
    • 리플렉션 등 동적인 기술을 쓸때 꼭 필요한 조건이다.
  • final 클래스, enum, interface, inner 클래스 사용불가하다.
  • 저장할 필드에 final 사용할 수 없다.(당연하지만..)

@Entity 속성

  • 속성 : name
    • JPA에서 사용할 엔티티 이름을 지정한다.
    • 기본값은 클래스 이름을 그대로 사용한다.
    • 같은 클래스 이름이 없으면 가급적으로 기본값 사용.

@Table

  • @Table은 엔티티와 매핑할 테이블 지정
속성 기능 기본값
name 매핑할 테이블 이름 엔티티 이름
catalog 데이터베이스 catalog 매핑  
schema 데이터베이스 schema 매핑  
uniqueConstraints DDL생성 시에 유니크 제약 조건 생성  

 

'DB > JPA' 카테고리의 다른 글

필드와 컬럼 매핑  (0) 2022.12.31
데이터 베이스 스키마 자동생성  (0) 2022.12.30
준영속 상태  (0) 2022.12.30
플러시  (1) 2022.12.30
영속성 컨텍스트 2  (0) 2022.12.30

준영속 상태

  • 영속 → 준영속
  • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

준영속 상태로 만드는 방법

  • em.detach(entity)
    • 특정 엔티티만 준영속 상태로 전환
  • em.clear()
    • 영속성 컨텍스트를 완전히 초기화
  • em.close()
    • 영속성 컨텍스트를 종료

'DB > JPA' 카테고리의 다른 글

데이터 베이스 스키마 자동생성  (0) 2022.12.30
객체와 테이블 매핑  (0) 2022.12.30
플러시  (1) 2022.12.30
영속성 컨텍스트 2  (0) 2022.12.30
영속성 컨텍스트 1  (0) 2022.12.30

플러시

영속성 컨텍스트의 변경내용을 데이터베이스에 반영


플러시 발생

  • 변경 감지
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
  • 플러스가 발생한다고해서 commit이 되는건 아니다.

영속성 컨텍스트를 플러시 하는 방법

  • em.flush() - 직접 호출
    • 직접 쓸 일은 거의 없다.
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

JPQL 쿼리 실행시 플러시가 자동으로 호출되는 이유

em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//중간에 JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();

 

  • 위와 같은 상황일때 DB에 값이 없는 상황이 생길 수 있다.
  • 이런 상황을 방지하고자 기본모드가 flush()를 항상 수행하도록 설계되었다.

플러시는!

  • 영속성 컨텍스트를 비우지 않음
  • 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
  • 트랜잭션이라는 작업 단위가 중요 → 커밋 직전에만 동기화 하면 된다.

 

'DB > JPA' 카테고리의 다른 글

객체와 테이블 매핑  (0) 2022.12.30
준영속 상태  (0) 2022.12.30
영속성 컨텍스트 2  (0) 2022.12.30
영속성 컨텍스트 1  (0) 2022.12.30
JPA - 애플리케이션 개발  (0) 2022.12.30

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21687?category=questionDetail&q=385382

  1. 엔티티를 영속 시킨다.
    1. 내부의 1차캐시가 있다.
      1. @id (Key)
      2. Entity (Value)

이렇게 되면 무슨 이점이 있을까?


1. 1차 캐시에서 조회

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21687?category=questionDetail&q=385382

멤버객체를 저장하고 조회를 하면

jpa는 영속성 컨텍스트에서

  • 1차 캐시를 조회(DB를 바로 가지않음)

2. 데이터베이스에서 조회

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21687?category=questionDetail&q=385382

1차 캐시에 없는 데이터를 조회 해보자

  1. 1차 캐시를 조회(없는 상황)
  2. DB에서 조회
  3. 1차 캐시에 저장
  4. 해당 데이터 반환
  • 엔티티 매니저라는 것은 데이터베이스 트랜잭션 단위로 만들고 끝나면 종료된다.
  • 고객의 요청이 하나 들어와서 비즈니스가 끝나면 영속성 컨텍스트가 지워져서 1차 캐시가 지워져버려 그다지 큰 이득을 볼 수 있다곤 할 수 없다.

3. 영속 엔티티의 동일성 보장

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b);
  • 콘솔에 찍히는 값은 true 이다.
  • 1차 캐시로 반복 가능한 읽기(REPEEATABLE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공

4. 엔티티 등록 트랜잭션을 지원하는 쓰기 지연

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21687?category=questionDetail&q=385382&tab=curriculum

  • 영속성 컨텍스트 안에는 쓰기 지연 SQL 저장소 라는 것이 있다.
  1. persist(memberA)
  2. 1차캐시에 memberA 들어감
  3. 동시에 JPA가 엔티티를 분석하여 Insert Query 생성
  4. 쓰기지연 SQL 저장소에 쿼리 저장
  5. persist(memberB)
  6. 1차캐시에 memberB 들어감
  7. 동시에 JPA가 엔티티를 분석하여 Insert Query생성(현재 insert Query가 2개 저장되어 있음)
  8. transaction.commit();
  9. flush
    • 영속성 컨텍스트의 변경 내용을 DB 에 반영하는 것을 말한다
  10. commit

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21687?category=questionDetail&q=385382&tab=curriculum

5. 엔티티 수정 - 변경 감지

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
//em.update(member) 이런 코드가 있어야 하지 않을까?
transaction.commit(); // [트랜잭션] 커밋
  • 단순히 값만 바꿨지만
  • UPDATE Query가 실행되는걸 알 수 있다.
  • 비밀이 뭘까??

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21687?category=questionDetail&q=385382&tab=curriculum

  1. 바로 영속성 컨텍스트 안에 있다.
  2. 1차 캐시에는스냅샷이라는 것이 들어있다. 최초 시점의 상태를 스냅샷을 떠둔다.
  3. JPA는 commit하는 시점에 flush()가 호출된다.
  4. 이때 엔티티와 스냅샷을 비교한다.
  5. 비교를 해보고 바뀌었다면
  6. UPDATE Query를 쓰기 지연 저장소에 저장하고
  7. DB반영
  8. commit() 수행

'DB > JPA' 카테고리의 다른 글

객체와 테이블 매핑  (0) 2022.12.30
준영속 상태  (0) 2022.12.30
플러시  (1) 2022.12.30
영속성 컨텍스트 1  (0) 2022.12.30
JPA - 애플리케이션 개발  (0) 2022.12.30
더보기

💡 JPA에서 가장 중요한 2가지

  • 객체와 관계형 데이터베이스 매핑하기
  • 영속성 컨택스트

영속성 컨텍스트

엔티티 매니저 팩토리와 엔티티 매니저

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21686?category=questionDetail&q=385382

  • EntityManagerFactory를 통해서 고객의 요청이올때마다 EntityManager를 생성한다.
  • Entity 매니저는 내부적으로 데이터베이스 커넥션으로디비를 사용하게 된다.

영속성 컨텍스트

  • JPA를 이해하는데 가장 중요한 용어
  • “엔티티를 영구 저장하는 환경” 이라는 뜻

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21686?category=questionDetail&q=385382
https://www.inflearn.com/course/ORM-JPA-Basic/unit/21686?category=questionDetail&q=385382

  • 비영속(new/transient)
    • 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
      • 객체를 생성만 한 상태(셋팅만 한 상태)
      • JPA와 관련없음
  • 영속(managed)
    • 영속성 컨텍스트에 관리되는 상태
      • 엔티티매니저 안에는 영속 컨텍스트가 있다.
      • em.persist(객체)
      • 영속상태가 된다고해서 DB에 쿼리를 보내는 것이 아니다.
      • 트랜잭션을 commit 하는 시점에 쿼리가 실행된다.
  • 준영속(detached)
    • 영속성 컨텍스트에 저장되었다가 분리된 상태
      • em.detach(객체)
  • 삭제(removed)
    • 삭제된 상태
      • em.remove(객체)

왜 이런 매커니즘일까?

애플리케이션과 DB사이에 무언가 있다.!!

중간에 무언가 있으면 이점들을 누릴 수 있다.

'DB > JPA' 카테고리의 다른 글

객체와 테이블 매핑  (0) 2022.12.30
준영속 상태  (0) 2022.12.30
플러시  (1) 2022.12.30
영속성 컨텍스트 2  (0) 2022.12.30
JPA - 애플리케이션 개발  (0) 2022.12.30

JPA 구동 방식

https://www.inflearn.com/course/ORM-JPA-Basic/unit/21685?category=questionDetail&q=385382

  • Persistence 라는 클래스가 있다.
    • 설정정보를 조회하고
  • EntityManagerFactory를 만듬
    • EntityManager를 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
  • 인자 값은 어떻게 줘야할까??
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="hello"> //여기부분
        <properties>
            <!-- 필수 속성 -->
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

            <!-- 옵션 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            <!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
        </properties>
    </persistence-unit>
</persistence>
  • persistence-unit name= " " 이곳에 들어있는 이름을 넣어줘야한다.
package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();
        /*
        * code 위치
        * */
        em.close();
        emf.close();
    }
}
  • 위의 코드는 기본적인 구조이다.
  • 이제 DB에 MEMBER라는 테이블을 만들어보자.

 

  • 핑 하기 위한 Member 클래스 또한 만들어보자
package hellojpa;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Member {
    @Id
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • @Entity를 사용하여 JPA를 쓸것 이라고 알려준다.
  • PK와 매핑될 변수에 @Id를 붙여준다.
package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        //트랜잭션을 얻어온다.
        EntityTransaction tx = em.getTransaction();
        //트랜잭션 시작
        tx.begin();
        try{
            Member member = new Member();
            member.setId(1L);
            member.setName("HelloA");
            em.persist(member);

            //트랜잭션 종료
            tx.commit();
        }catch (Exception e){
            tx.rollback();
        } finally {
            em.close();
        }
        emf.close();
    }
}
  • EntityManagerFactory는 로딩시점에 딱 하나만 만들어놔야한다.
  • 실제 디비에 저장하거나 트랜잭션 단위별로 EntityManger를 만들어야한다.

실행결과로 디비에 저장되는 것을 알 수 있다.

  • 조회
    • Member findMember = em.find(Member.class, 1L);
      • 인자로 클래스정보와 pk값을 넣어준다.
  • 삭제
    • em.remove(findMember);
    • 인자로 객체 인스턴스를 넣어준다.
  • 수정
    • findMember.setName("HelloJPA")
    • 단지 객체 내부의 이름을 변경하는 코드를 적었더니?
    • 값이 바뀌는것을 확인할 수 있었다.
    • 어떻게 자바객체에서 값만 바꿨는데 이게 가능한 걸까?
      • JPA를 통해서 Entity를 가져오면 JPA가 관리하고 commit하는 시점에 다 체크한다.
      • 바뀐점이 있다면 UPDATE 쿼리를 대신 실행해준다.

 

  • 주의
    • 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유
    • 엔티티 매니저는 쓰레드간에 공유하면안되고 사용하면 버려야 한다.
    • JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

JPQL

  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • 문제는 검색 쿼리
  • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색을 해야한다.
    • 자바 코드에서 멤버 테이블이 있구나, 멤버 객체가 있구나라고 생각을 가지고 개발해야 한다.
  • 근데, 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다.
  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하다.
  • 그래서 JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다.
  • SQL과 문법이 유사하고, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN등을 지원한다.
  • JPQL은 엔티티 객체를 대상으로 쿼리를 질의하고
  • SQL은 데이터베이스 테이블을 대상으로 쿼리를 질의한다.

 

'DB > JPA' 카테고리의 다른 글

객체와 테이블 매핑  (0) 2022.12.30
준영속 상태  (0) 2022.12.30
플러시  (1) 2022.12.30
영속성 컨텍스트 2  (0) 2022.12.30
영속성 컨텍스트 1  (0) 2022.12.30

Serialization(직렬화)

  • 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트 형태로 데이터를 변환하는 기술
  • 각자 PC의 OS마다 서로 다른 가상 메모리 주소 공간을 갖기 때문에, Reference Type의 데이터들은 인스턴스를 전달 할 수 없다.
  • 따라서, 이런 문제를 해결하기 위해선 주소값이 아닌 Byte형태로 직렬화된 객체 데이터를 전달해야 한다.
  • 직렬화된 데이터들은 모두 기본형이 되고, 이는 파일 저장이나 네트워크 전송 시 파싱이 가능한 유의미한 데이터가 된다. 따라서 전송 및 저장이 가능한 데이터로 만들어 주는 것이 바로 직렬화이다.

직렬화 조건

  • 자바에서는 간단히 java.io.Serializable 인터페이스 구현으로 직렬화/역직렬화가 가능하다.
  • 직렬화 대상
    • 인터페이스 상속 받은 객체,
    • Primitive 타입의 데이터
  • Primitive 타입이 아닌 Reference 타입처럼 주소값을 지닌 객체들은 바이트로 변환하기 위해 Serializable 인터페이스를 구현해야 한다.

직렬화 방법

  • java.io.ObjectOutputStream 객체를 이용한다.
Member member = new Member("홍길동", "hong@hong.com", 25);
    byte[] serializedMember;
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(member);
            // serializedMember -> 직렬화된 member 객체 
            serializedMember = baos.toByteArray();
        }
    }
    // 바이트 배열로 생성된 직렬화 데이터를 base64로 변환
    System.out.println(Base64.getEncoder().encodeToString(serializedMember));
}

역직렬화 조건

  • 직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 한다.
    • 중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 한다.

  💡 자바 직렬화 대상 객체는 동일한 serialVersionUID를 가지고 있어야 한다(필수는 아님)

자바의 직렬화 왜 사용될까?

  • CSV, JSON 프로토콜 버퍼 등은 시스템의 고유 특성과 상관없는 대부분의 시스템에서의 데이터 교환 시 많이 사용된다. 하지만 자바 직렬화 형태의 데이터 교환은 자바 시스템 간의 데이터 교환을 위해서 존재한다.

그렇다면 자바에서도 CSV, JSON을 사용하면 되지 자바 직렬화를 써야 되는 이유가 있을까?

  • 정답은 없지만 목적에 따라 적절하게 써야한다.
  • 직렬화의 장점
    • 자바 시스템에서 개발에 최적화 되어 있다.
    • 복잡한 데이터 구조의 클래스의 객체라도 직렬화 기본 조건만 지키면 큰 작업 없이 바로 직렬화가 가능하다.
    • 데이터 타입이 자동으로 맞춰진다.
  • 직렬화의 단점
    • 변경에 취약하기 때문에 예외사항이 발생할 가능성이 높다.
    • 다른 포맷에 비해서 용량이 크다.

자바 직렬화는 언제 어디서 사용될까?

  • 서블릿 세션
    • 서블릿 기반의 WAS들은 대부분 세션의 자바 직렬화를 지원하고 있다. 물론 단순히 세션을 서블릿 메모리 위에서 운용한다면 직렬화를 필요로 하지 않지만 파일로 저장하거나 세션 클러스터링, DB를 저장하는 옵션 등을 선택하게 되면 세션 자체가 직렬화 되어 저장되어 전달된다.
  • 캐시
    • 자바 시스템에서 퍼포먼스를 위해 캐시 라이브러리 시스템을 많이 이용하게 된다. 개발을 하다보면 상당수의 클래스가 만들어지게 된다 예를들어 DB를 조회한 후 가져온 데이터 객체 같은 경우 실시간 형태로 요구하는 데이터가 아니라면 메모리, 외부 저장소, 파일 등을 저장소를 이용해서 데이터 객체를 저장한 후 동일한 요청이 오면 DB를 다시 요청하는 것이 아니라 저장된 객체를 찾아서 응답하게 하는 형태를 보통 캐시를 사용한다고 한다.
    • 이렇게 캐시할 부분을 직렬화하여 저장해서 사용한다. 자바 직렬화만을 이용해서 캐시를 저장하지는 않지만 가장 간편하기 때문에 많이 사용된다.

'Computer science > JAVA' 카테고리의 다른 글

Object Class  (0) 2023.01.01
String Class  (0) 2023.01.01
오토 박싱 & 오토 언박싱  (0) 2022.12.25
Primitive type & Reference type  (0) 2022.12.24
Call by value와 Call by reference  (0) 2022.12.24

Auto boxing & Auto unboxing

자바에는 기본 타입과 Wrapper 클래스가 존재한다.

  • 기본 타입 : int, long, float, double, boolean 등
  • Wrapper 클래스 : Integer, Long, Float, Double, Boolean 등

Wrapper 클래스란?

  • 자바의 자료형은 크게 기본타입과 참조타입으로 나누어짐
  • 프로그래밍을 하다 보면 기본타입의 데이터를 객체로 표현해야 하는 경우가 종종 있다.

  • 이럴 때에 기본타입을 객체로 다루기 위해 사용하는 클래스는 Wrapper 클래스라고한다.

  • 래퍼 클래스의 주요 용도는 기본 타입의 값을 박싱 해서 포장 객체로 만드는 것이지만, 문자열을 기본 타입 값으로 변환할 때에도 사용된다. 대부분의 래퍼 클래스에는 parse + 기본 타입명으로 되어있는 정적 메서드가 있다. 이 메서드는 문자열을 매개 값으로 받아 기본 타입 값으로 변환한다.

  • 래퍼 객체는 내부의 값을 비교하기 위해 == 연산자를 사용할 수 없다. 이 연산자는 내부의 값을 비교하는 것이 아니라 래퍼 객체의 참조 주소를 비교하기 때문이다.

  • 래퍼 클래스와 기본자료형과의 비교는 == 연산과 equals연산 모두 가능하다. 그 이유는 컴파일러가 자동으로 오토박싱과 언박싱을 해주기 때문이다.

Boxing 과 Unboxing

출처 : https://coding-factory.tistory.com/547

  • 기본 타입의 값을 포장 객체로 만드는 과정을 박싱이라고함.

  • 반대로 포장객체에서 기본 타입의 값을 얻어내는 과정을 언박싱이라고한다.

AutoBoxing 과 AutoUnboxing

  • 기본타입 값을 직접 박싱, 언박싱 하지 않아도 자동으로 박싱과 언박싱이 일어나는 경우가 있다.

  • 자동 박싱의 포장 클래스 타입에 기본값이 대입될 경우에 발생한다.

  • 예를 들어 int타입의 값을 Integer 클래스 변수에 대입하면 자동 박싱이 일어나 힙 영역에 Integer객체가 생성된다.
  • Java에서 아무리 기능적 편의성을 위하여 박싱과 언박싱 그리고 오토박싱을 제공하지만 명백히 다른 타입간의 형변환은 어플리케이션의 성능에 영향을 미칠 수 밖에 없다. 
  • 아무리 작은 차이가 존재한다고 할지라도 어플리케이션의 성능측면에서 봤을때 반드시 필요한 상황(1건이라던가 대용량이 아닐때)이 아니라면 지양해야하는 기능일 것이다

'Computer science > JAVA' 카테고리의 다른 글

String Class  (0) 2023.01.01
Serialization(직렬화)  (0) 2022.12.25
Primitive type & Reference type  (0) 2022.12.24
Call by value와 Call by reference  (0) 2022.12.24
JAVA의 컴파일과정(JVM 메모리 구조, JVM GC)  (0) 2022.12.24

Primitive type & Reference type

자바에는 기본형과 참조형이 있다. 일반적인 분류는 다음과 같다.

Java Data Type
ㄴ Primitive Type
    ㄴ Boolean Type(boolean)
    ㄴ Numeric Type
        ㄴ Integral Type
            ㄴ Integer Type(short, int, long)
            ㄴ Floating Point Type(float, double)
        ㄴ Character Type(char)
ㄴ Reference Type
    ㄴ Class Type
    ㄴ Interface Type
    ㄴ Array Type
    ㄴ Enum Type
    ㄴ etc.

Primitive type(기본형 타입)

  • 자바에서는 총 8가지의 Primitive type을 미리 정의하고 제공한다.
  • 자바에서 기본 자료형은 반드시 사용하기 전에 선언 되어야 한다.
  • os에 따라 자료형의 길이가 변하지 않는다.
  • 비객체 타입이다. 따라서 null값을 가질 수 없다. 만약 Primitive type에 Null을 넣고 싶다면 Wrapper Class를 활용할 수 있다.
  • Stack 메모리에 저장된다.

https://gyoogle.dev/blog/computer-language/Java/Primitive%20type%20&%20Reference%20type.html

  • boolean
    • 논리형인 boolean 기본값은 false이며 참, 거짓을 저장하는 타입이다.
    • 실제로 1bit면 충분하지만, 데이터를 다루는 최소 단위가 1byte이므로 메모리 크기가 1byte이다.
  • byte
    • byte는 주로 이진데이터를 다루는데 사용되는 타입이다.
  • short
    • C언어와의 호환을 위해 사용되는 타입으로 잘 사용되지 않는다.
  • int
    • int형은 자바에서 정수 연산을 하기 위한 기본 타입이다. 즉 byte 혹은 short의 변수가 연산을 하면 연산의 결과는 int형이 된다.
  • long
    • 수치가 큰 데이터를 다루는 프로그램에서 주로 사용한다.
    • long 타입의 변수를 초기화 할 때는 정수값 뒤에 알파벳 L을 붙여서 long타입의 정수 데이터임을 알려주어야 한다. 만일 정수값이 int의 값의 저장 범위를 넘는 정수에서 L을 붙이지 않는다면 컴파일 에러가 발생한다.
  • float, double
    • 실수를 가수와 지수 형식으로 저장하는 부동소수점 방식으로 저장된다.
    • 가수를 표현하는데 있어 double형이 float형보다 표현 가능 범위가 더 크므로 double형이 보다 정밀하게 표현할 수 있다.
    • 자바에서 실수의 기본 타입은 double형이므로 float형에는 알파벳 F를 붙여서 float 형임을 명시해주어야 한다.

Reference type(참조형 타입)

  • 자바에서 Primitive 타입을 제외한 모든 타입은 Reference 타입이다.
  • Reference 타입은 JAVA에서 최상인 java.lang.Object클래스를 상속하는 모든 클래스들을 말한다. 물론 new로 인하여 생성하는 것들은 메모리 영역인 Heap 영역에 생성하게되고, GC가 돌면서 메모리를 해제한다.
  • 클래스 타입, 인터페이스 타입, 배열 타입, 열거 타입이 있다.
  • 빈 객체를 의미하는 NULL이 존재한다.

  • 문법상으로는 에러가 없지만 실행시켰을 때 생기는 런타입 에러가 발생한다. 예를 들어 객체나 배열을 NULL 값으로 받으면 NullPointException이 발생하므로 변수값을 넣어야 한다.

  • Heap 메모리에 생성된 인스턴스는 메서드나 각종 인터페이스에 접근하기 위해 JVM의 Stack 영역에 존재하는 Fram에 일종의 포인터인 참조값을 가지고 있어 이를 통해 인스턴스를 핸들링한다.

String Class

  • 클래스 형에서도 String클래스는 조금 특별하다. 이 클래스는 참조형에 속하지만 기본형 처럼 사용한다.

  • 불변하는 객체이다.

  • String 클래스에는 값을 변경해주는 메서드들이 존재하지만 해당 메서드를 통해 데이터를 바꾼다 해도 새로운 String 클래스 객체를 만들어내는 것이다. 일반적으로 기본형 비교는 == 연산자를 사용하지만 String 객체간의 비교는 .equals() 메서드를 사용해야 한다.

'Computer science > JAVA' 카테고리의 다른 글

String Class  (0) 2023.01.01
Serialization(직렬화)  (0) 2022.12.25
오토 박싱 & 오토 언박싱  (0) 2022.12.25
Call by value와 Call by reference  (0) 2022.12.24
JAVA의 컴파일과정(JVM 메모리 구조, JVM GC)  (0) 2022.12.24

Call by value(값에 의한 호출)

  • 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시공간이 생성된다.
  • call by value호출 방식은 함수 호출 시 전달되는 변수 값을 복사해서 함수 인자로 전달한다.
  • 이때 복사된 인자는 함수 안에서 지역적으로 사용되기 때문에 local value 속성을 가짐
  • JAVA의 경우 함수에 전달되는 인자의 데이터 타입에 따라서 함수 호출 방식이 달라진다.
    • 기본 자료형 : call by value
    • 참조 자료형 : call by reference

Call by reference(참조에 의한 호출)

  • 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다.
  • 자바의 경우, 항상 call by value로 값을 넘긴다.
  • C/C++와 같이 변수의 주소값 자체를 가져올 방법이 없으며, 이를 넘길 수 있는 방법 또한 있지 않다.
  • reference type(참조 자료형)을 넘길 시에는 해당 객체의 주소값을 복사하여 이를 가지고 사용한다.
  • 따라서 원본 객체의 프로퍼티까지는 접근이 가능하나, 원본 객체 자체를 변경할 수는 없다.

'Computer science > JAVA' 카테고리의 다른 글

String Class  (0) 2023.01.01
Serialization(직렬화)  (0) 2022.12.25
오토 박싱 & 오토 언박싱  (0) 2022.12.25
Primitive type & Reference type  (0) 2022.12.24
JAVA의 컴파일과정(JVM 메모리 구조, JVM GC)  (0) 2022.12.24

+ Recent posts