<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>gony-dev 님의 블로그</title>
    <link>https://gony-dev.tistory.com/</link>
    <description>Back 없는 백엔드 개발자 gony입니다!</description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 15:45:17 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>minarinamu</managingEditor>
    <image>
      <title>gony-dev 님의 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/7229118/attach/5b2b91bd06b4429e8244521813759353</url>
      <link>https://gony-dev.tistory.com</link>
    </image>
    <item>
      <title>공유 자원 접근 시 일어나는 Race Condition?</title>
      <link>https://gony-dev.tistory.com/79</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Situation&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 리팩터링 작업 중, 댓글 생성 기능을 검토하다가 쿼리문에 문제 발생 우려가 제기되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;댓글 생성 기능은 댓글과 대댓글의 생성 로직이 달라 API를 분리하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;댓글 객체에는 댓글 그룹을 지정하기 위해 commentGroup 필드를 생성하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1768202414716&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Comment extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = &quot;writer_id&quot;, nullable = false)
    private Member writer;

    @Column(nullable = false, length = 500)
    private String content;

    @Column(nullable = false)
    private Long authorId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = &quot;feed_id&quot;, nullable = false)
    private Feed feed;

    @Column
    private Long commentGroup; // 대댓글을 위한 댓글 ID

    public Comment(Member writer, String content, Long author, Feed feed, Long commentGroup) {
        this.writer = writer;
        this.content = content;
        this.authorId = author;
        this.feed = feed;
        this.commentGroup = commentGroup;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 (대댓글이 아닌) 댓글 생성 로직이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;commentGroup을 지정하기 위해 repository 내에서 다음 그룹을 지정하는 쿼리문에서 &quot;레이스 컨디션&quot;이 일어난 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;레이스 컨디션(Race Condition)이란?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레이스 컨디션은 2개 이상의 프로세스나 스레드가 공유 자원을 서로 사용하려고 경쟁하는 현상을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 공유 자원은 멀티 스레드 환경에서 프로세스 내의 자원 사용을 모두 공유한다는 점에서 동기화 문제가 발생한다.&lt;/p&gt;
&lt;pre id=&quot;code_1768203393060&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public Long nextCommentGroup(Feed feed) {
        Long max = queryFactory
                .select(comment.commentGroup.max())
                .from(comment)
                .where(comment.feed.eq(feed))
                .fetchOne();
        return (max == null) ? 1L : max + 1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드의 경우에는 댓글을 생성하기 위해 피드에 해당하는 댓글 그룹의 최대값 + 1을 반환하는 쿼리문이다. 이때 발생하게 될 문제를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 댓글이 2개 이상 생성될 경우, 동시에 max를 읽을 것이고 둘다 같은 값을 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 동일한 commentGroup을 반환할 테고 동시성 문제가 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 댓글이 생성되지 않는 문제는 아니다. 현재 같은 commentGroup 내의 댓글은 만들어진 순서에 따라 댓글과 대댓글로 구분되기 &lt;br /&gt;때문에 조금이라도 더 늦은 댓글이 먼저 생성된 댓글에 대한 대댓글로 만들어지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제는 UX적으로도 사용자에게 불편함을 증대시키기 때문에 해결해야할 필요성을 느꼈다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Task&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 당장의 해결 방안을 모색하기 보다는 현재 주어진 상황을 다시 한 번 되새겨 보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;댓글은 만들어진 댓글들에 대한 commentGroup 중 최댓값 다음으로 배치되어 생성된다. 그런 과정에서 querydsl을 사용하여 최댓값을 도출하게 되는데 이때 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이러한 문제는 &quot;락(Lock)&quot;을 사용하여 문제를 해결하는 흔한 동시성 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 락은 완벽한 기술이 아니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동시에 들어온 요청이 락 대기 상태에 걸림 -&amp;gt; TPS 저하&lt;/li&gt;
&lt;li&gt;지연 시간 증가&lt;/li&gt;
&lt;li&gt;데드락 위험&lt;/li&gt;
&lt;li&gt;운영/디버깅 난이도 상승&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 단점으로 인해 필자는 구현시에 마지막 선택지로서 락을 선택한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 락 대신 commentGroup 생성 기준을 다시 생각해보기로 했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Action&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 comment 객체는 comment 테이블 내에 있는 commentGroup 중 최댓값 + 1을 해서 만들어진다.&lt;br /&gt;그리고 대댓글은 댓글의 commentGroup + 1씩하여 늘어나게 되는 구조였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;지금 생각해보면 왜 저렇게 짰을까?&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;commentGroup은 주요 목적이 댓글에 대한 대댓글을 조회해주기 위한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 쿼리문으로 최댓값을 조회하는 것이 아닌 댓글 생성 시 만들어지는 pk를 기준으로 만들기로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 되면 별도의 시퀀스가 없이도 동시성 이슈가 없다!&lt;/p&gt;
&lt;pre id=&quot;code_1768890517796&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Transactional
@Override
public void createComment(String email, Long postId, CommentReqDto reqDto) {

    Member writer = findIfEmailExists(email);
    Feed feed = findIfFeedExist(postId);
    Long authorId = feed.getMember().getId();

    Comment comment = new Comment(writer, reqDto.content(),
            authorId, feed);
    commentRepository.save(comment);
    comment.updateCommentGroup(comment.getId());

    log.info(&quot;{} 피드에 대한 댓글 생성 완료&quot;, feed.getId());
}


// Comment.updateCommentGroup
public void updateCommentGroup(Long groupId) {
    this.commentGroup = groupId;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  Result&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TestCode&lt;/p&gt;
&lt;pre id=&quot;code_1768891707866&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
void concurrentTest() {
	ExecutorService es = Executors.newFixedThreadPool(32);
    
    for(int i=0;i&amp;lt;10;i++){
    	es.submit(() -&amp;gt; {
        	commentService.createComment(&quot;email&quot;, &quot;postId&quot;, CommentReqDto reqDto);
        });
    }
    
    assertThat(commentRepository.).isEqualTo(10);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 결과 성공이었다!&lt;/p&gt;</description>
      <category>TroubleShooting</category>
      <category>java</category>
      <category>race condition</category>
      <category>spring</category>
      <category>동시성</category>
      <category>레이스 컨디션</category>
      <category>스프링</category>
      <category>자바</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/79</guid>
      <comments>https://gony-dev.tistory.com/79#entry79comment</comments>
      <pubDate>Sun, 1 Feb 2026 14:39:31 +0900</pubDate>
    </item>
    <item>
      <title>추상 클래스? 알려드리겠습니다!</title>
      <link>https://gony-dev.tistory.com/78</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지난 시간에는 자바에서 빠질 수 없는 객체 지향 클래스에 대해 알아보고 실습해보았다!&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/77&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JAVA] - JAVA의 꽃, 객체 지향 프로그래밍(OOP)의 클래스 문법&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;이번에는 구체적이지 않지만 중요한 &quot;Abstract&quot;에 대해 알아보도록 하자.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추상화?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상적이라는 단어는 현실의 구체적인 형태나 모습이 아닌 여러 사물에서 공통된 속성을 뽑아내어 만든 개념 또는 관념적인 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 우리가 실습하며 작성해왔던 클래스는 구체적으로 데이터를 담아 인스턴스화하여 다루었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 배우게 될 추상 클래스는 &lt;u&gt;구현부가 없는 메서드를 포함하여 자식 클래스에서 반드시 구현화해야하는 클래스&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 인스턴스화가 불가능하며, 선언 시 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;abstract&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&quot; 키워드를 추가해야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AS5JB/dJMcahiTlDU/n4JKxBUopk6DlAsM0tuGfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AS5JB/dJMcahiTlDU/n4JKxBUopk6DlAsM0tuGfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AS5JB/dJMcahiTlDU/n4JKxBUopk6DlAsM0tuGfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAS5JB%2FdJMcahiTlDU%2Fn4JKxBUopk6DlAsM0tuGfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;472&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 지향 프로그래밍에서 듣게 되는 '추상화'랑 동일하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서울의 지리를 추상화시켜 보여주는 서울 지하철 노선도가 그 예시가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 추상화를 클래스에 접목시킨 추상 클래스에 대해 더 자세히 알아보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추상 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추상 클래스&lt;/b&gt;&lt;u&gt;는 추상화 개념을 추가하여 구조적으로 객체를 설계하고, 기능 수정이나 추가를 포함하여 전체적인 유지보수성을 높여준다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 개별 프로젝트보다는 범용 라이브러리나 프레임워크 시스템을 설계하는데 유용하게 작용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(ex. String.toUpperCase(), for, while)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 추상 클래스를 간단하게 작성한 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1768895023234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 추상 클래스
public abstract class Player {
	private int level;
    private int power;
    private String nickname;
    
    public Player(String nickname) {
        this.level = 1;
        this.power = 30;
        this.nickname = nickname;
    }
    
    public abstract void levelUp();
}

// 상속받은 클래스
class Archer extends Player {
	
    public void levelUp() {
    	System.out.println(&quot;궁수&quot; + this.nickname + &quot;님이 레벨업하였습니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상 클래스 내에 선언된 abstract를 가진 메서드는 &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;추상 메서드&lt;/b&gt;&lt;/span&gt;라고 하며, 저렇게 미완성인 채로 완성한다.(?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;미완성으로 남겨놓는 이유는 추상 클래스를 상속 받는 자식 클래스에 따라 상속 받는 메서드의 내용이 달라지기 때문이다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 실제 내용은 상속 받는 클래스에서 구체적으로 구현하도록 비워둔다고 생각하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;추상 클래스 생성자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;추상 클래스는 인스턴스 객체를 생성할 수 없다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상 클래스는 구체화하지 않기 때문에 객체에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;구체적인 설정이 불가능&lt;/span&gt;하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오로지 부모 클래스로서 상속시키기 위한 개념으로 작용되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 반드시 추상 클래스를 어떤 자식 클래스에 상속시키고, 자식 클래스를 인스턴스화하여 사용해야만 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1768895968720&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 추상 클래스
public abstract class Player {
    private int level;
    private int power;
    private String nickname;
    
    public Player(String nickname) {
        this.level = 1;
        this.power = 30;
        this.nickname = nickname;
    }
    
    public abstract void levelUp();
}

// 상속받은 클래스
class Archer extends Player {
	
    public Archer(String name) {
    	super(name);
        this.power = 20;
    }
    
    public void levelUp() {
    	System.out.println(&quot;궁수&quot; + this.nickname + &quot;님이 레벨업하였습니다.&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상화는 생각보다 어렵지 않은 개념이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 OOP에서는 빠질 수 없는 개념이므로 확실히 이해하고 넘어가야 한다고 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상 클래스를 기반으로 공통 기능들을 미리 정의해두고, 이를 상속받은 실제 클래스에서 필요한 부분만 확장하거나 구체화하면 코드 구조가 확실히 명확해진다. 결과적으로 중복 코드를 줄이고, 변경이 생겼을 때 영향 범위를 최소화할 수 있어 유지보수성을 높일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 관점에서 추상 클래스를 잘 설계해주면, 개발자는 공통적으로 필요한 부분만 오버라이딩하여 구현만 하면 되기 때문에 개발 비용이 줄어들고, &lt;b&gt;구현에만 온전히 집중할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추상화는 단순한 문법이 아니다. 협업과 확장성을 위한 설계 도구임을 확실히 짚고 넘어가자!&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>abstract</category>
      <category>java</category>
      <category>OOP</category>
      <category>객체 지향 프로그래밍</category>
      <category>자바</category>
      <category>추상 메서드</category>
      <category>추상 클래스</category>
      <category>추상화</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/78</guid>
      <comments>https://gony-dev.tistory.com/78#entry78comment</comments>
      <pubDate>Tue, 20 Jan 2026 18:00:38 +0900</pubDate>
    </item>
    <item>
      <title>JAVA의 꽃, 객체 지향 프로그래밍(OOP)의 클래스 문법</title>
      <link>https://gony-dev.tistory.com/77</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지난 시간에는 배열에 대해 알아보고 코드에 적용하는 시간을 가졌다.&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/76&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JAVA] - JAVA 배열을 모르겠다고? 알려드리겠습니다!&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;이번 시간에는 객체 지향 프로그래밍에서 필수적인 요소인 클래스에 대해 파헤쳐 보자!&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;객체 지향 프로그래밍(Object Oriented Programming)이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt9lXK/dJMcad1Ii9g/pPHPr5gg9K5xqAA061iMD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt9lXK/dJMcad1Ii9g/pPHPr5gg9K5xqAA061iMD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt9lXK/dJMcad1Ii9g/pPHPr5gg9K5xqAA061iMD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt9lXK%2FdJMcad1Ii9g%2FpPHPr5gg9K5xqAA061iMD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;503&quot; height=&quot;359&quot; data-origin-width=&quot;1513&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;객체&quot; 개념을 기반으로 데이터를 속성과 기능으로 묶어 프로그램을 설계하는 방식으로 줄여서 OOP라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 현실 세계에서의 의미 그대로 '사물'을 의미하며, 클래스라는 '설계도'를 기반으로 만들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #6164c6;&quot;&gt;다형성&lt;/span&gt;&lt;/b&gt;(Polymorphism), &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;추상화&lt;/span&gt;&lt;/b&gt;(Abstraction), &lt;b&gt;&lt;span style=&quot;color: #ffb5ef;&quot;&gt;상속&lt;/span&gt;&lt;/b&gt;(Inheritance), &lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;캡슐화&lt;/span&gt;&lt;/b&gt;(Encapsulation)의 4대 특징을 통해 &lt;u&gt;코드 재사용성 및 유지보수, 확장성을 높히는 것이 목표&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 객체 지향 프로그래밍을 설계하기 위해 클래스에 대해 자세히 알아볼 예정이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클래스(Class)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;클래스 지리구욘~&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스를 알아보기 전에 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;클래스가 왜 필요한지&lt;/b&gt;&lt;/span&gt;에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스란 객체를 정의하는 설계도란 의미로 사용된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자바에서는 설계도를 통해 여러 객체를 생성하여 사용하는 식으로 프로그래밍을 진행한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;게임을 예로 들어보자.&lt;br /&gt;게임을 시작하면 모든 플레이어의 체력, 공격력, 스킬 같은 &amp;lsquo;속성의 종류&amp;rsquo;는 모두 동일한 구조를 가진다.&lt;br /&gt;하지만 플레이가 진행되면서 플레이어마다&amp;nbsp;체력 수치가 오르고,&amp;nbsp;새로운 스킬을 배우는 등 값(=데이터)은 달라진다.즉, 변하는 건 &amp;ldquo;속성 자체&amp;rdquo;가 아니라 &amp;ldquo;속성에 들어있는 값&amp;rdquo;이다.&lt;br /&gt;이때, 플레이어가 생성될 때마다 매번 새로 설계해서 만드는 건 비효율적이다. &lt;br /&gt;그래서 플레이어의 공통 구조를 &amp;lsquo;설계도&amp;rsquo;로 정의해두고, 공장처럼 필요할 때마다 찍어내듯 생성하는데, &lt;br /&gt;이 설계도가 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;클래스&lt;/b&gt;&lt;/span&gt;&quot;이고, 설계도로 만들어진 실제 플레이어가 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;객체&lt;/b&gt;&lt;/span&gt;&quot;다.&lt;/blockquote&gt;
&lt;p data-end=&quot;356&quot; data-start=&quot;247&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;517&quot; data-start=&quot;358&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;517&quot; data-start=&quot;358&quot; data-ke-size=&quot;size16&quot;&gt;클래스는 객체의 속성을 나타내는 필드와 객체의 함수를 나타내는 메서드로 구성되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTDonz/dJMcaaxcZ7H/yDDD6PEn32JkbiGVJY0HwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTDonz/dJMcaaxcZ7H/yDDD6PEn32JkbiGVJY0HwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTDonz/dJMcaaxcZ7H/yDDD6PEn32JkbiGVJY0HwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTDonz%2FdJMcaaxcZ7H%2FyDDD6PEn32JkbiGVJY0HwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;531&quot; height=&quot;461&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래밍을 하며 클래스, 인스턴스, 객체 등 많은 용어들이 나온다.&lt;br /&gt;용어들을 정리해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클래스&lt;/b&gt; | 객체를 생성하는 설계도&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체&lt;/b&gt; | 클래스와 new 연산자를 통해 만든 실제 데이터가 들어있는 변수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인스턴스&lt;/b&gt; | 클래스로부터 생성된 특정 개체, 관계적인 표현&lt;/li&gt;
&lt;li&gt;&lt;b&gt;필드&lt;/b&gt;(속성) | 클래스 내에 있는 변수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메서드&lt;/b&gt; | 클래스 내에 있는 함수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;생성자&lt;/b&gt; | 클래스로 객체를 만들 때 각 객체의 변수를 초기 생성해 줄 수 있는 메서드&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;(객체 == 인스턴스) ? true : false&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 언급했듯이 클래스를 통해 객체와 인스턴스가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 객체는 클래스를 통해 만들어지고, 인스턴스도 클래스를 통해서 만들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과연 이 둘은 같은 걸까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 통해 알아보자.&lt;/p&gt;
&lt;pre id=&quot;code_1767763220650&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Player { // 클래스(설계도) 선언
    	int level;
        int healthPower;
        
        public Player() {
        	this.level = 1;
            this.healthPower = 10;
        }
        
        public String levelUp() {
        	return &quot;Level Up!&quot;;
        }
    }
public class MyClass {
    
    public static void main(String[] args) {
    	
        Player p1 = new Player(); // 객체 생성, p1은 Player의 인스턴스
        Player p2 = new Player();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Player 클래스를 선언하고, p1이라는 객체를 생성하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;p1은 힙 영역에 할당된 구체적인 실체&lt;/u&gt;를 가지며, 이때부터 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&quot;p1은 Player의 인스턴스&quot;&lt;/u&gt;&lt;/span&gt;라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 객체는 &lt;u&gt;개념적&lt;/u&gt;이고, 인스턴스는 &lt;u&gt;실제적인 개념&lt;/u&gt;을 갖는 관점이라고 이해하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;필드(Field)란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;클래스 필드는 클래스에 선언된 변수&lt;/b&gt;&lt;/u&gt;를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 클래스 필드는 선언된 위치와 선언자에 따라 아래와 같이 구분된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;u&gt;클래스 변수&lt;/u&gt; | static 키워드로 선언된 변수&lt;/li&gt;
&lt;li&gt;&lt;u&gt;인스턴스 변수&lt;/u&gt; | static 키워드로 선언되지 않은 변수&lt;/li&gt;
&lt;li&gt;&lt;u&gt;지역 변수&lt;/u&gt; | 메서드나 블록 내에서 선언되고 소멸되는 변수&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JVM에서 변수 종류에 대해 학습하였을 때 나온 변수들로 다시 한 번 상기시켜보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/69&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JVM] - 자바 코드의 메모리 영역&lt;/a&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style11&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;생성 시기&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;소멸 시기&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;저장 영역&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;클래스 변수&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;클래스가 메모리에 올라갈 때&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;프로그램이 종료될 때&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;Method Area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;인스턴스 변수&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;인스턴스가 생성될 때&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;인스턴스가 소멸할 때&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;Heap Area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;지역 변수&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;블록 내 선언문이 실행될 때&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;블록을 벗어날 때&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;Stack Area&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메서드(Method)란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드는 &lt;u&gt;&lt;b&gt;우리가 흔히 접하게 될 개념으로 클래스 내의 함수&lt;/b&gt;&lt;/u&gt;를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 작업을 수행하기 위해 선언하며, &lt;u&gt;클래스의 기능을 정의&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 모체 언어인 C에서는 '메서드'가 아닌 '함수'로서 작용하지만, 이름만 다를 뿐이니 크게 신경 쓰지 않아도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드는 생성 및 호출 시 다음과 같은 구성요소들을 필요로 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;접근 제어자&lt;/b&gt; | 해당 메서드에 접근할 수 있는 외부 범위 명시&lt;/li&gt;
&lt;li&gt;&lt;b&gt;반환 타입&lt;/b&gt; | 메서드가 코드를 실행하고 최종적으로 반환할 데이터 타입 명시&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메서드명&lt;/b&gt; | 메서드를 호출하기 위한 이름 명시&lt;/li&gt;
&lt;li&gt;&lt;b&gt;매개변수&lt;/b&gt; | 메서드를 정의할 때 입력으로 전달된 값을 받는 변수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인수&lt;/b&gt; | 메서드 호출 시 넘겨주는 입력값&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767765215482&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Player {

    private String nickname = &quot;&quot;; // 인스턴스 변수

    public String getNickname() {
        return nickname;
    }

    public Player(String nickname) { // 생성자 생성
        this.nickname = nickname;
    }

    public static String noti(){ // 클래스 메서드 생성
        return &quot;캐릭터가 생성되었습니다!&quot;;
    }
}
public class MyClass {

    public static void main(String[] args) {

        Player p1 = new Player(&quot;John&quot;); // 생성자 호출
        System.out.println(Player.noti()); // 클래스 메서드 호출
        System.out.println(&quot;해당 플레이어 이름은 &quot; +p1.getNickname()); // 인스턴스 메서드 호출
        Player p2 = new Player(&quot;Jane&quot;);
        System.out.println(Player.noti());
        System.out.println(&quot;해당 플레이어 이름은 &quot; + p2.getNickname());


    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드도 변수와 마찬가지로 클래스 메서드와 인스턴스 메서드가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static 선언 유무에 따라 구분이 가능하며, 클래스 메서드는 메서드 내부에서 인스턴스 변수를 사용할 수 없다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 메서드 내부에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드를 클래스 메서드로 정의하는 것을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드를 보면 noti를 통해 플레이어가 생성될 때마다 생성 알림을 출력하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 클래스 메서드는 모든 인스턴스에 공통으로 적용되는 정보나 로직을 실행할 경우에만 사용하고,&lt;br /&gt;인스턴스 메서드인 getNickname은 유동적으로 변할 수 있는 인스턴스 변수를 다루는 경우에 사용하는 것이 좋다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;생성자(Constructor)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 위에서 몇 번의 실습을 통해 경험해 봤지만 다시 정리해보면, &lt;br /&gt;생성자는 &lt;b&gt;&lt;u&gt;객체가 생성될 때 동적으로 인스턴스 변수 초기화를 위해 실행되는 메서드&lt;/u&gt;&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자에는 몇 가지 특징이 존재한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;생성자의 목적은 &lt;span style=&quot;color: #ee2323;&quot;&gt;객체 초기화&lt;/span&gt;임.&lt;/li&gt;
&lt;li&gt;생성자 이름은 클래스명과 &lt;span style=&quot;color: #ee2323;&quot;&gt;반드시&lt;/span&gt; 동일해야함.&lt;/li&gt;
&lt;li&gt;new를 통해 객체 생성 시, 생성자는 객체당 &lt;span style=&quot;color: #ee2323;&quot;&gt;한 번만 호출&lt;/span&gt;함.&lt;/li&gt;
&lt;li&gt;생성자는 객체가 생성될 때 반드시 호출됨.&lt;/li&gt;
&lt;li&gt;생성자는 &lt;span style=&quot;color: #ee2323;&quot;&gt;리턴 타입이 없으며&lt;/span&gt;, 지정할 수도 없음.&lt;/li&gt;
&lt;li&gt;개발자가 생성자를 작성하지 않았으면 &lt;span style=&quot;color: #ee2323;&quot;&gt;컴파일러가 자동으로 생성자를 생성&lt;/span&gt;해줌.&lt;/li&gt;
&lt;li&gt;생성자는 &lt;span style=&quot;color: #ee2323;&quot;&gt;오버로딩&lt;/span&gt;을 통해 여러 개 작성이 가능함.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;오버로딩(Overloading)이란?&lt;br /&gt;자바의 한 클래스 내에서 생성된 메서드에 대해 같은 이름을 가진 메서드가 있더라도 매개변수의 개수나 타입이 다르면 같은 이름을 사용하여 메서드를 정의하는 개념&lt;br /&gt;&lt;br /&gt;메서드명이 같고, 매개변수의 개수나 타입이 달라야 하는 것이 필수 조건이며, 리턴 값만 다른 경우에는 오버로딩을 할 수 없다.&lt;/blockquote&gt;
&lt;pre id=&quot;code_1767950208579&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Player {
	int level;
    int power;
    int job;
    
    public Player(int lv, int po, String job) { // 생성자 생성
        this.level = lv;
        this.power = po;
        this.job = job;
    }
}
public class MyClass {
	
    public static void main(String[] args) {
    	Player p1 = new Player(1, 40, &quot;궁수&quot;);
        Player p2 = new Player(1, 80, &quot;전사&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 구현해 간단한 클래스를 작성해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 생성자 안의 this를 볼 수 있는데, 해당 키워드는 클래스(=설계도) 자신을 나타내는 키워드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'this' 자체가 인스턴스의 주소를 가리키고 있기 때문에 자기 자신에게 접근이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this를 변수가 아닌 메서드로도 적용할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자 내부에서만 사용 가능하며, this() 메서드에 인수를 전달하면, 이미 정의되어 있는 다른 생성자를 찾아 호출해 준다!&lt;/p&gt;
&lt;pre id=&quot;code_1767950457448&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Player {
	int level;
    int power;
    int job;
    
    public Player(int lv, int po, String job) { // 생성자 생성
        this.level = lv;
        this.power = po;
        this.job = job;
    }
    
    Player() {
    	this(1, 50, &quot;도적&quot;); // this 메서드 사용
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클래스 상속(Extend)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상속이란 개념은 자바 문법 작성 시 매우 많이 보게 될 요소 중 하나이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서의 상속은 &lt;u&gt;&lt;b&gt;상위 클래스와 자식 클래스 간의 관계를 나타내는 단어&lt;/b&gt;&lt;/u&gt;로, &lt;br /&gt;자식 클래스가 부모 클래스의 특징을 상속받아 사용할 수 있다는 의미이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nm821/dJMcahXrt0T/bzLxYI908kGQ86mLKR5c30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nm821/dJMcahXrt0T/bzLxYI908kGQ86mLKR5c30/img.png&quot; data-alt=&quot;[출처] https://coding-factory.tistory.com/865&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nm821/dJMcahXrt0T/bzLxYI908kGQ86mLKR5c30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNm821%2FdJMcahXrt0T%2FbzLxYI908kGQ86mLKR5c30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;457&quot; height=&quot;251&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[출처] https://coding-factory.tistory.com/865&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상속을 통해 클래스 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;재사용 효율을 높혀주고, 코드 시간을 단축시킬 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 상속에도 몇 가지 제한이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부모 클래스의 &lt;u&gt;private&lt;/u&gt; 접근 제어자에 대한 요소들은 자식 클래스가 상속 받을 수 없다.&lt;/li&gt;
&lt;li&gt;부모와 자식 클래스가 서로 다른 패키지에 있다면, 부모의 default 접근 제한을 갖는 필드나 메서드를 자식이 상속 받을 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 통해 이해해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1767951660098&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Player {

    int level;
    int power;
    String nickname;

    public Player(String nickname) { // 부모 클래스 생성자
        this.level = 1;
        this.power = 30;
        this.nickname = nickname;
    }
}
class Archer extends Player {
    public Archer(String nickname) { // 자식 클래스 생성자
        super(nickname); // super 메서드로 부모 클래스 생성자 특징 가져가기
        this.power = 40;
    }

    void kingShot(){...}
}
class Warrior extends Player {
    public Warrior(String nickname) {
        super(nickname);
        this.power = 80;
    }

    void strike() {...}
}
class Thief extends Player {
    public Thief(String nickname) {
        super(nickname);
        this.power = 50;
    }
    void stealth() {...}
}
public class MyClass {

    public static void main(String[] args) {

        Archer p1 = new Archer(&quot;Jane&quot;);
        Warrior p2 = new Warrior(&quot;타락파워전사&quot;);
        Thief p3 = new Thief(&quot;백엔드 개발자&quot;);


    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Player를 상속받은 Archer, Warrior, Thief 자식 클래스를 생성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 각각의 자식 클래스는 부모 클래스의 특성을 물려받아 level, power, nickname 필드를 재생성할 필요가 없으며, &lt;br /&gt;클래스 생성 목적에 맞게 유용하게 다루어 사용하면 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 보지 못했던 것이 있는데, 바로 'super()'이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this처럼 목적에 따라 키워드 또는 메서드로 사용할 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;super &lt;b&gt;키워드&lt;/b&gt; | 자식 클래스가 부모 클래스의 필드나 메서드를 참조하는데 사용&lt;/li&gt;
&lt;li&gt;super &lt;b&gt;메서드&lt;/b&gt; | 부모 클래스의 생성자를 호출&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상대적으로 super가 this보다 빈번하게 사용되기 때문에 사용법을 확실히 알아두는 것이 좋다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메서드 재정의(Method Overriding)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드 재정의란 &lt;u&gt;&lt;b&gt;상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 것을 의미&lt;/b&gt;&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오버로딩과 다소 어감이 비슷하나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;오버로딩은 기존에 없던 새로운 메서드를 정의하는 것이고,&lt;/u&gt;&lt;br /&gt;&lt;u&gt;오버라이딩은 상속받은 클래스의 메서드를 &lt;b&gt;재정의&lt;/b&gt;하는 것이다.&lt;/u&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1768140726519&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Player {

    int level;
    int power;
    String nickname;

    public Player(String nickname) { // 부모 클래스 생성자
        this.level = 1;
        this.power = 30;
        this.nickname = nickname;
    }
    
    public void intro() {
    	System.out.println(&quot;Player가 무직 클래스로 생성되었습니다!&quot;);
    }
}
class Archer extends Player {
    public Archer(String nickname) { // 자식 클래스 생성자
        super(nickname); // super 메서드로 부모 클래스 생성자 특징 가져가기
        this.power = 40;
    }
    
    public void intro() { // 메서드 오버라이딩
    	System.out.println(&quot;Player가 궁수 클래스로 생성되었습니다!&quot;);
    }

    void kingShot(){...}
}
public class MyClass {

	public static void main(String[] args) {
    	Archer ar = new Archer();
        ar.intro();
    }

}
/*
Player가 궁수 클래스로 생성되었습니다!
*/&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Import&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'import'란 키워드는 &lt;u&gt;&lt;b&gt;클래스 내에서 코드 상단에 패키지를 명시해주면 해당 패키지 내의 클래스 파일을 사용할 수 있게 해준다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 파일을 가져올 때 특정 파일만 가져올 지, 해당 패키지의 모든 클래스 파일을 가져올지 선택할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 패키지 뒤에 '*' 키워드만 붙혀주면 모든 클래스 파일을 사용할 수 있다!&lt;/p&gt;
&lt;pre id=&quot;code_1768141365440&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays; // java.util에 있는 Arrays 클래스 파일을 가져와 사용한다.
import java.lang.*; //  java.lang 패키지 내에 있는 모든 클래스 파일을 가져와 사용한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드처럼 import를 꺼낼 수 있는데, 이때 &quot;java.*&quot;를 하면 그냥 코드 한 줄만 입력할 수 있지 않을까라는 생각을 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정답은 &quot;안된다&quot;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'*'는 모든 클래스 파일들을 포함하게 하지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;해당 패키지에 포함된 하위 패키지의 클래스까지 포함시켜 주지는 않는다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 위에 코드처럼 java.utils와 java.lang에 있는 클래스 파일들을 사용하고 싶다면, 따로따로 명시해 주어야 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;static import&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;import static&quot; 문을 사용하면 정적 메서드나 필드를 클래스명 없이 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드를 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1768142011961&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import static java.lang.System.out; // static 선언

public class MyClass {
	
    public static void main(String[] args) {
    	out.println(&quot;Hello World!&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위를 보면 static import를 통해 System.out을 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 되면 출력 코드 작성 시에는 System.out을 제외한 out부터 사용하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;제어자(Modifier)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어자란 클래스와 메서드 등 다양한 곳에서 사용되는 키워드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스트에서 직접적으로 언급했던 제어자는 접근 제어자 밖에 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 static이나 final 같은 키워드도 제어자라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;접근 제어자&lt;/b&gt; | private, protected, public, default&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기타 제어자&lt;/b&gt; | static, final, abstract etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 접근 제어자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OOP에서는 사용자로부터 숨겨야 하는 정보들이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접근 제어자는 클래스와 클래스의 멤버를 사용할 때, &lt;u&gt;&lt;b&gt;접근할 수 있는 범위를 지정해 주는 역할&lt;/b&gt;&lt;/u&gt;을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접근 제어자는 4가지로 접근 범위 지정이 가능하다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;private&lt;/b&gt; | 같은 클래스 내에서만 접근 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;default&lt;/b&gt; | 같은 패키지 내에서만 접근 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;protected&lt;/b&gt; | 같은 패키지나 다른 패키지의 자손 클래스에서 접근이 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;public&lt;/b&gt; | 접근 제한 X&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 기타 제어자&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2-1. Static&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;u&gt;&lt;b&gt;static 멤버는 메모리 영역 내 메서드 영역에 생성&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 클래스의 모든 객체에 의해 공유가 가능하며, this 사용이 불가능하다.(인스턴스가 아니기 때문이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2-2. final&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;u&gt;&lt;b&gt;final 키워드는 값의 변경이 불가능하다는 것을 명시하는 키워드&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;final은 상수(=constant) 풀에 저장되며, &lt;u&gt;오버라이딩을 통한 재정의가 불가능하다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스에 final을 명시할 시, 해당 클래스에 대한 다른 클래스가 상속을 받을 수 없다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 제어자 조합&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제어자끼리의 조합은 다양하게 사용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 사용이 불가능한 제어자 조합이 있으며, 대상에 따라 다르게 적용된다&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클래스에 final과 abstract는 함께 사용 불가&lt;/li&gt;
&lt;li&gt;메서드에 static과 abstract는 함께 사용 불가&lt;/li&gt;
&lt;li&gt;메서드에 private과 abstract는 함께 사용 불가&lt;/li&gt;
&lt;li&gt;메서드에 private과 final에 함께 사용 불가&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1- &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5OOP-%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%AC%B8%EB%B2%95-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2- &lt;a href=&quot;https://velog.io/@dongvelop/Java-%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B0%9D%EC%B2%B4-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@dongvelop&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>CLASS</category>
      <category>java</category>
      <category>OOP</category>
      <category>객체 지향 프로그래밍</category>
      <category>자바</category>
      <category>클래스</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/77</guid>
      <comments>https://gony-dev.tistory.com/77#entry77comment</comments>
      <pubDate>Mon, 12 Jan 2026 14:08:40 +0900</pubDate>
    </item>
    <item>
      <title>JAVA 배열을 모르겠다고? 알려드리겠습니다!</title>
      <link>https://gony-dev.tistory.com/76</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이전 시간에는 기본형 타입의 실수, 정수형에 대해 형변환하는 원리와 실습을 학습해보았다.&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/75&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JAVA] - JAVA 타입 형변환&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;이번 시간에는 프로그래밍을 하며 결코 빠질 수 없는 배열에 대해 알아보자!&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 자료형이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열은 이전 시간까지 배웠던 Primitive Type이 아닌 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;Reference Type에 해당하는 자료형&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;으로,&lt;br /&gt;하나의 타입에 대해 여러 데이터들을 모아 구조적으로 다룰 수 있게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성하는 각각의 값을 &lt;u&gt;배열 요소&lt;/u&gt;(element)라고 하며, 위치를 가리키는 숫자를 &lt;u&gt;인덱스&lt;/u&gt;(index)라고 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열을 생성해보자!&lt;/h3&gt;
&lt;pre id=&quot;code_1767531593466&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int[] nums = new int[100]; // int형 배열 생성
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;

char[] chArr = new char[100]; // char형 배열 생성
chArr[0] = 'a';
chArr[1] = 'b';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 자바 프로그램에서 int와 char형의 배열을 각각 생성하는 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 배열은 선언 시, &lt;span style=&quot;color: #009a87;&quot;&gt;&lt;u&gt;&lt;b&gt;고정된 크기를 가져야 하며 배열 길이를 반드시 지정해야 한다!&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수동으로 선언하고 초기화해야 한다는 단점이 있기 때문에 배열의 길이를 처음부터 지정하지 않으면 &lt;u&gt;컴파일 오류가 발생&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 생성한 배열은 &lt;u&gt;인덱스 번호를 통해 특정 데이터에 접근하여 데이터 삽입 또는 수정 작업을 실행&lt;/u&gt;할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 출력&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열에 데이터를 넣어주면서 테스트나 결과물을 보기 위해 배열 내 데이터를 출력하고 싶을 때가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1767532607577&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int[] nums = {1, 2, 3, 4, 5};

System.out.println(nums);
// 출력 결과 : [I@3fee733d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 배열 변수를 출력해보면 원하던 결과는 나오지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 결과처럼 이상한 값이 나오게 되는데, 이것은 배열의 주소값을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;그렇다면 내가 원하는 결과는??&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 내 데이터를 출력하고 싶다면 보통 두 가지 방법을 많이 사용한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;for문을 사용하여 배열 순회&lt;/li&gt;
&lt;li&gt;Arrays.toString() 메서드 사용&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1767533132293&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {
	int[] nums = {1, 2, 3, 4, 5};

	for(int i=0;i&amp;lt;nums.length;i++){
		System.out.println(nums[i]);
	}

	System.out.println(Arrays.toString(nums));
}
/* 출력 결과
1
2
3
4
5
[1, 2, 3, 4, 5];
/*&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예외적으로, char형 배열은 println()으로 바로 출력이 가능하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 복사&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말했듯 자바에서 배열은 선언 시 고정된 크기를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 원래 계획했던 것보다 배열 공간이 추가로 필요하다면 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 세 가지의 해결방법이 제공된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;기존의 배열을 새로 만든 배열에 복사&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Arrays.copyOf() 메서드 사용&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;System.arraycopy() 메서드 사용&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나씩 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 기존 배열을 새로 생성한 배열에 복사&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767535285744&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {
	
    public static void main(String[] args){
    	int[] nums = {1, 2, 3, 4, 5};
        int[] newArr = new int[nums.length * 2];
        
        for(int i=0;i&amp;lt;nums.length;i++){
        	newArr[i] = nums[i];
        }
        nums = newArr;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새 배열을 생성하고, for-loop를 통해 기존 배열의 값들을 새 배열에 넣어주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 원래의 배열을 가리키던 nums가 새로 생성된 newArr을 가리키도록 지정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이 방법은 &lt;span style=&quot;color: #ee2323;&quot;&gt;3가지 방법 중 성능이 가장 떨어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 복사하면서 &lt;u&gt;추가 작업이 필요하거나 실습용으로 사용하는 것을 권장&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. System.arraycopy() 메서드 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767536429523&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

	public static void main(String[] args) {
    	int[] nums = {1, 2, 3, 4, 5};
        int[] newArr = new int[nums.length * 2];
        
        // System.arraycopy(복사할 배열, 복사를 시작할 배열 인덱스 값, 복사받을 배열, 복사된 배열값들이 붙여질 시작위치, 지정된 길이만큼 값들이 복사)
        System.arraycopy(nums, 0, newArr, 0, nums.length);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;System.arraycopy() 메서드는 방법들 중 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;가장 빠르며, 부분 복사 지원이 명확하다는 특징&lt;/span&gt;&lt;/b&gt;이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본형 타입 뿐만 아니라 참조형 타입에서도 사용이 가능하지만, &lt;u&gt;5개의 인자를 정확히 입력하는 것을 주의해야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Arrays.copyOf() 메서드 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767536761982&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {
	
    public static void main(String[] args){
    	int[] nums = {1, 2, 3, 4, 5};
        
        // Arrays.copyOf(복사할 배열, 할당받을 배열 길이);
        int[] newArr = Arrays.copyOf(nums, nums.length * 2);
        System.out.println(Arrays.toString(newArr));
        
    }
}
/* 출력결과
[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Arrays.copyOf() 메서드는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;기존의 배열을 특정 길이만큼 복사하여 새로운 배열에 할당하는 메서드&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;가장 간결하고 가독성이 좋으며, 새로운 배열의 길이가 더 길다면 나머지는 기본값으로 채워진다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깔끔한 코드를 구현하고 싶다면 제일 권장되는 방식이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 정렬&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무작위로 배치된 배열 값들을 Arrays.sort()를 이용해 정리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 통해 알아보자.&lt;/p&gt;
&lt;pre id=&quot;code_1767538700326&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {
        int[] nums = {6, 3, 2, 5, 4};

        // 오름차순
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums));

        // 부분 정렬
        int[] arr = {9, 1, 4, 2, 6};
        Arrays.sort(arr, 0, 3);
        System.out.println(Arrays.toString(arr));
    }
}
/* 출력결과
[2, 3, 4, 5, 6]
[1, 4, 9, 2, 6]
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복사와 마찬가지로 Arrays 메서드를 사용하면 정렬이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 여기서 내림차순 구현은 보이지 않는데 이는 &lt;u&gt;자바 기본형 타입에 대한 내림차순 정렬 메서드가 존재하지 않기 때문이다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 오름차순 정렬 후 뒤집거나 Integer 같은 객체 타입을 사용하여 Comparator 클래스를 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이 부분은 후에 다루어질 예정이다.)&lt;/p&gt;
&lt;pre id=&quot;code_1767539203963&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

	public static void main(String[] args){
    	int[] nums = {6, 3, 2, 5, 4};
        Arrays.sort(nums); // 오름차순 정렬
        
        // 오름차순 정렬 후 뒤집기 구현
        for(int i=0, j = nums.length-1; i&amp;lt;j; i++, j--) {
        	int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 비교&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 두 배열을 서로 비교하고 싶다면 두 가지 방안 중 하나를 사용하면 된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;for-loop를 통해 순회하여 비교&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Arrays.equals() 메서드 사용&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1767590055376&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {
        int[] nums = {6, 3, 2, 5, 4};
        int[] nums2 = {6, 3, 2, 5, 4};

        // 1. for-loop를 통해 배열 순회
        for(int i = 0; i&amp;lt;nums.length; i++){
            if(nums[i] != nums2[i]){
                System.out.println(&quot;Not equal to &quot; + nums[i] + &quot; and &quot; + nums2[i]);
                return;
            }
        }

        // 2. Arrays.equals() 메서드로 배열 비교
        System.out.println(Arrays.equals(nums, nums2)); // 배열 내 인덱스마다의 요소들이 같으므로 true

        Arrays.sort(nums);
        System.out.println(Arrays.equals(nums, nums2)); // nums의 오름차순 정렬 후 요소들이 인덱스마다 같지 않으므로 false
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방법 모두 성능은 비슷하지만, 동작이나 안정성의 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;for-loop의 경우&lt;/b&gt;&lt;u&gt;,&lt;/u&gt; &lt;u&gt;일부 구간만 비교가 필요한 경우나 특정 규칙을 적용하는 커스텀 방식을 이용할 수 있지만&lt;/u&gt;&lt;br /&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;코드 일부분 누락이나 인덱스 실수로 인해 비교적 버그가 나기 쉽다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Arrays.equals()의 경우&lt;/b&gt;에는 &lt;u&gt;배열 요소들이 같은지에 대한 유무가 명확하며 동일성 체크를 깔끔하게 처리한다.&lt;/u&gt;&lt;br /&gt;&lt;u&gt;또한 타입별로 정의가 명확하기 때문에&lt;/u&gt; &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;&quot;두 배열이 같은지&quot;만 비교한다면 Arrays.equals() 메서드를 사용하는 것을 권장한다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다차원 배열&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 배운 배열은 모두 1차원 배열이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열은 좀더 고차원적으로 설계하는 것이 가능한데 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;2차원 이상의 배열을 정의하는 것을 다차원 배열&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;이라고 하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 요소로 배열을 갖는 배열이라고 생각하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2차원 배열&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원 배열은 점에서 선이 되는 것처럼 1차원 배열이 모여 만들어지는 개념이라고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 학생의 과목 점수를 배열에 담기 위해서는 {90, 80, 80, 85} 처럼 1차원 배열을 생성하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 여러 명의 학생을 담기 위해서는 어떻게 하면 될까? 2차원 배열을 생성하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원 배열은 테이블 형태의 데이터를 적재하기 위해 사용되며, &lt;b&gt;&lt;u&gt;행&lt;/u&gt;&lt;/b&gt;(row)과 &lt;b&gt;&lt;u&gt;열&lt;/u&gt;&lt;/b&gt;(column)의 개념만 알면된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;국어&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;영어&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;수학&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;철수&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;90&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;85&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;90&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;영희&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;70&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;90&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;90&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;영수&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;85&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;100&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 표가 곧 테이블이며, 이를 2차원 배열로 생성하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1767591474112&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {
        int[][] students = {{90, 85, 90}, {70, 90, 90}, {85, 100, 80}}; // 학생당 국영수 점수

        for(int i=0; i&amp;lt;students.length; i++){
            System.out.println(&quot;학생&quot; + (i+1) + &quot; 의 국영수 점수는 &quot; + Arrays.toString(students[i]));
        }
        // or
        
        System.out.println(Arrays.deepToString(students);
    }
}
/*
학생1 의 국영수 점수는 [90, 85, 90]
학생2 의 국영수 점수는 [70, 90, 90]
학생3 의 국영수 점수는 [85, 100, 80]
[[90, 85, 90], [70, 90, 90], [85, 100, 80]]
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 선언과 동시에 데이터를 넣어주었지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전에 초기화를 진행하고 싶다면, 1차원 배열 초기화에 대괄호를 한 번 더 추가하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 new int[3][3]이라는 첫번째 괄호는 행 개수를, 두번째 괄호는 열의 개수를 나타내는 배열이 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력방법에는 2가지가 있는데 1차원 배열 출력과 비슷하다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;for-loop를 이용해 배열 내 배열 출력&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Arrays.deepToString() 메서드를 사용&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;가변 배열&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열은 기본적으로 고정된 길이를 가지고 있어야 하는 것이 맞다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원 배열 역시 테이블 형태라고 해서 가로와 세로의 길이가 모두 같아야 할 것 같은데, 그렇지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;자바에서 다차원 배열은 각 요소로 들어가는 1차원 배열의 길이를 각기 다르게 해도 2차원 배열을 생성하는데 문제가 없다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(물론 2차원 배열이 아닌 다차원 배열도 가능하다!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1767594180859&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {
        int[][] score = {
                {100, 100, 100, 100},
                {20, 20, 20},
                {30, 30},
                {40, 40},
                {50, 50, 50}
        };

        System.out.println(Arrays.deepToString(score));
    }
}
/* 출력결과
[[100, 100, 100, 100], [20, 20, 20], [30, 30], [40, 40], [50, 50, 50]]
*/&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;객체 배열&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 기본형 타입들에 대해 배열을 생성해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 객체 타입을 배열에 넣어 사용하는 방법에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 또한 하나의 자료형으로 취급되기에 배열을 생성하는데 문제가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 알아두어야 하는 점은&lt;u&gt; 객체 타입은 참조를 사용한다는 점을 유의해야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드를 살펴보자.&lt;/p&gt;
&lt;pre id=&quot;code_1767595360297&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {

        class Obj{
            String str;
            int num;

            public Obj(String str, int num) {
                this.str = str;
                this.num = num;
            }
        }

        Integer[] arr = {1, 3, 5, 7};

        System.out.println(&quot;Integer Array : &quot; + Arrays.toString(arr));

        Obj[] objArr = {new Obj(&quot;str1&quot;, 1), new Obj(&quot;str2&quot;, 2)};
        System.out.println(&quot;Obj Array : &quot; + Arrays.toString(objArr));
    }
}
/* 출력 결과
Integer Array : [1, 3, 5, 7]
Obj Array : [MyClass$1Obj@4617c264, MyClass$1Obj@36baf30c]

*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 두 객체 타입(Integer, Obj)에 대해 배열을 생성하고 출력해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Integer에 대해서는 실제값이 잘 출력되는 반면, Obj에 대해서는 주소값 형태가 출력되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 서로 다른 값의 타입이 출력되는 것은 toString에 대한 메서드 유무에 따라 달라지기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Integer 같은 래퍼 클래스는 toString()이 내부에서 이미 구현되어 있어 실제 값이 출력되지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Obj는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;toString()이 구현되어 있지 않아&lt;/u&gt;&lt;/span&gt; 저런 형태가 출력되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얼핏 보면 주소값 같지만 정확히는 &quot;&lt;u&gt;해시 기반 식별 문자열&lt;/u&gt;&quot;이라는 점을 알아두자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;객체 배열 복사&lt;/h4&gt;
&lt;pre id=&quot;code_1767596008616&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {

        Obj[] objArr = {new Obj(&quot;str1&quot;, 1), new Obj(&quot;str2&quot;, 2)};
        System.out.println(&quot;Obj Array : &quot; + Arrays.toString(objArr));

        Obj[] objArr2 = objArr.clone();
        System.out.println(&quot;Obj Array2 : &quot; + Arrays.toString(objArr2));
    }
}
/* 출력 결과
Obj Array : [MyClass$1Obj@5acf9800, MyClass$1Obj@4617c264]
Obj Array2 : [MyClass$1Obj@5acf9800, MyClass$1Obj@4617c264]
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 타입으로 이루어진 배열도 복사가 가능하다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 출력 결과를 보면 식별 문자열이 같은 것을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 실제값의 복사와 함께 참조값이 함께 복사되었기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2bZlr/dJMcahwj10H/8W6mELWCTarhLCTmkYYHe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2bZlr/dJMcahwj10H/8W6mELWCTarhLCTmkYYHe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2bZlr/dJMcahwj10H/8W6mELWCTarhLCTmkYYHe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2bZlr%2FdJMcahwj10H%2F8W6mELWCTarhLCTmkYYHe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;295&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(배열 변수명).clone() 메서드는 배열만 새로 만들고 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;배열 안의 원소는 그대로 같은 객체를 가리키는 참조값을 복사한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 출력 시 각 원소가 같은 객체를 가리키기 때문에 똑같은 문자열이 출력되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우, 한쪽 배열에서 원소 객체를 수정하면 다른 배열에서도 객체가 수정되기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Obj 객체 자체를 새로 생성하여 넣어주는 것을 권장한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;객체 배열 정렬&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 배열에서 객체들을 정렬하기 위해서는 Arrays.sort() 메서드만으로 정렬되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Obj 클래스만 해도 str과 num 중 어느 것을 정렬할 것인지에 따라 정렬 기준이 달라지기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경우 Comparable 인터페이스와 Comparator 클래스를 이용한 객체 배열 정렬 방법을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Comparable 인터페이스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 같은 타입의 인스턴스를 서로 비교해야 할때 Comparable 인터페이스를 구현하여 compareTo() 메서드를 재정의한다.&lt;/p&gt;
&lt;pre id=&quot;code_1767599730222&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

public class MyClass {

    public static void main(String[] args) {

        class Obj implements Comparable&amp;lt;Obj&amp;gt; {
            String str;
            int num;

            public Obj(String str, int num) {
                this.str = str;
                this.num = num;
            }

            @Override
            public int compareTo(Obj o) {

                if(this.num &amp;gt; o.num) {
                    return 1;
                } else if(this.num == o.num) {
                    return 0;
                } else {
                    return -1;
                }
            }
        }

        Obj[] objArr = {new Obj(&quot;str1&quot;, 9), new Obj(&quot;str2&quot;, 2), new Obj(&quot;str3&quot;, 4)};
        System.out.println(&quot;정렬 전&quot;);
        for (Obj obj : objArr) {
            System.out.println(&quot;str : &quot; + obj.str + &quot;  num : &quot; + obj.num);
        }

        Arrays.sort(objArr);
        System.out.println(&quot;정렬 후&quot;);
        for(Obj obj : objArr) {
            System.out.println(&quot;str : &quot; + obj.str + &quot;  num : &quot; + obj.num);
        }
    }
}
/* 출력 결과
정렬 전
str : str1  num : 9
str : str2  num : 2
str : str3  num : 4
정렬 후
str : str2  num : 2
str : str3  num : 4
str : str1  num : 9
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;compareTo 메서드의 비교는 -1, 0, 1로 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반드시 -1, 0, 1로 나눌 필요는 없으며, 두 값을 비교하여 나온 결과에 따라 값을 반환해도 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;this.num &amp;gt; o.num | 양수 -&amp;gt; this가 뒤&lt;/li&gt;
&lt;li&gt;this.num == o.num | 0 -&amp;gt; 정렬 x&lt;/li&gt;
&lt;li&gt;this.num &amp;lt; o.num | 음수 -&amp;gt; this가 앞&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 프로젝트에 적용하거나 코딩 테스트 시에는 오버플로우의 위험 때문에 Integer.compare 메서드를 사용하는 것을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Comparator 클래스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Comparator 클래스를 통해 객체 정렬이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1767600378482&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.Comparator;

public class MyClass {

    public static void main(String[] args) {

        class Obj {
            String str;
            int num;

            public Obj(String str, int num) {
                this.str = str;
                this.num = num;
            }
        }

        Obj[] objArr = {new Obj(&quot;str1&quot;, 9), new Obj(&quot;str2&quot;, 2), new Obj(&quot;str3&quot;, 4)};
        System.out.println(&quot;정렬 전&quot;);
        for (Obj obj : objArr) {
            System.out.println(&quot;str : &quot; + obj.str + &quot;  num : &quot; + obj.num);
        }

        Comparator&amp;lt;Obj&amp;gt; byNumAsc = new Comparator&amp;lt;&amp;gt;() {
            @Override
            public int compare(Obj a, Obj b) {
                return Integer.compare(a.num, b.num);
            }
        };
        /* 람다 표현식으로 교체
		Comparator&amp;lt;Obj&amp;gt; byNumAsc = (a, b) -&amp;gt; Integer.compare(a.num, b.num);
        -&amp;gt; 메서드로 교체
        Comparator&amp;lt;Obj&amp;gt; byNumAsc = Comparator.comparingInt(a -&amp;gt; a.num);
        */
        

        Arrays.sort(objArr, byNumAsc);
        System.out.println(&quot;정렬 후&quot;);
        for(Obj obj : objArr) {
            System.out.println(&quot;str : &quot; + obj.str + &quot;  num : &quot; + obj.num);
        }
    }
}
/* 출력 결과
정렬 전
str : str1  num : 9
str : str2  num : 2
str : str3  num : 4
정렬 후
str : str2  num : 2
str : str3  num : 4
str : str1  num : 9
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Compareable에서 설명했던 compareTo() 메서드를 사용하여 Compartor를 구현했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 직접 구현을 했지만 주석처리한 코드를 보면 &lt;u&gt;람다로 더 짧게 코딩하거나 메서드만으로도 구현이 가능하다!&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내림차순은 Comparator에 reversed 메서드만 추가하면 되니 어렵게 생각하지 말고 구현해보자!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1- &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9E%90%EB%B0%94-%EB%B0%B0%EC%97%B4Array-%EB%AC%B8%EB%B2%95-%EC%9D%91%EC%9A%A9-%EC%B4%9D%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2- &lt;a href=&quot;https://simplex3510.tistory.com/214&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;simplex3510.tistory&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>1차원 배열</category>
      <category>2차원 배열</category>
      <category>java</category>
      <category>가변 배열</category>
      <category>객체 배열</category>
      <category>배열</category>
      <category>배열 정렬</category>
      <category>자바</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/76</guid>
      <comments>https://gony-dev.tistory.com/76#entry76comment</comments>
      <pubDate>Tue, 6 Jan 2026 12:00:58 +0900</pubDate>
    </item>
    <item>
      <title>JAVA 타입 형변환</title>
      <link>https://gony-dev.tistory.com/75</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지난 시간에는 JAVA 기본형 타입들에 대해 자세히 알아보았다.&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/74&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JAVA] - JAVA 기본형 데이터 타입&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;이번에는 JAVA 타입들의 형변환 원리에 대해 알아보고 이를 어떻게 적용하는지 알아보도록 하겠다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;타입 변환&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;하나의 타입을 본인 타입 제외하고 다른 타입으로 바꾸는 것을 타입 변환 or 형변환&lt;/b&gt;&lt;/u&gt;이라고 한다.&lt;br /&gt;프로그래밍 실행 동안에는 반드시 같은 타입끼리 값의 대입이나 연산을 수행할 수 있다.&lt;br /&gt;그래서 같은 기본형 타입 정수형이라고 해도 타입(int, long..)이 다르면 같은 타입으로 변환해주어야하기 때문에 형변환 작업이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 변환에는 규칙이 존재한다. 메모리에 할당받은 바이트의 크기가 상대적으로 작은 타입에서 큰 타입으로의 변환은 생략할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 메모리에 할당받은 바이트의 크기가 큰 타입에서 작은 타입으로의 변환은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;데이터 손실이 발생&lt;/u&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 상대적으로 바이트의 크기가 작은 타입으로 형변환을 할 경우 자바 컴파일러는 오류를 발생시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 형변환에는 두 가지 방법이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나는 묵시적 형변환과, 다른 하나는 명시적 형변환이 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;묵시적 형변환&lt;/b&gt; | 높은 자료형으로 변환&lt;/li&gt;
&lt;li&gt;&lt;b&gt;명시적 형변환&lt;/b&gt; | 낮은 자료형으로 변환&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;묵시적 형변환&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;프로그램 실행 도중에 컴파일러가 자동으로 타입 변환을 일으키는 것을 의미하는 형변환&lt;/b&gt;&lt;/span&gt;이며, 자동 형변환, 묵시적 형변환, 암시적 형변환 다양한 이름으로 불린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 작은 크기의 자료형에서 큰 크기의 자료형으로 변환할 때만 자동 타입이 변환한다. 왜냐하면 &lt;u&gt;자바에서는 데이터 손실이 발생하지 않거나, 데이터 손실이 최소화되는 방향으로 자동 타입 변환을 진행하기 때문이다.&lt;/u&gt;(ex. short -&amp;gt; int)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gc2y3/dJMcaiaVoqi/DZ8KuyD7SQjTretka9fRS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gc2y3/dJMcaiaVoqi/DZ8KuyD7SQjTretka9fRS0/img.png&quot; data-alt=&quot;아래에서 계속 이 도식화 자료를 사용할 예정이니 참고!!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gc2y3/dJMcaiaVoqi/DZ8KuyD7SQjTretka9fRS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGc2y3%2FdJMcaiaVoqi%2FDZ8KuyD7SQjTretka9fRS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1464&quot; height=&quot;250&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아래에서 계속 이 도식화 자료를 사용할 예정이니 참고!!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 플로우를 통해 이해해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;byte 타입은 1 byte 크기를 갖고, long 타입은 8 byte 크기를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아래 코드처럼 구현해도 자동으로 형변환이 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1372&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r0x3e/dJMcaiWf6hG/t856Jwr5wCtSv0DAw8EE7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r0x3e/dJMcaiWf6hG/t856Jwr5wCtSv0DAw8EE7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r0x3e/dJMcaiWf6hG/t856Jwr5wCtSv0DAw8EE7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr0x3e%2FdJMcaiWf6hG%2Ft856Jwr5wCtSv0DAw8EE7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1372&quot; height=&quot;394&quot; data-origin-width=&quot;1372&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 도식화된 변환표를 보면 이상한 점이 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 long에서 float로의 변환이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;long 타입은 8 byte이고, float는 4 byte인데 어떻게 변환이 될까?&lt;/b&gt; 그 이유는 메모리 설계상 정수 타입보다 실수 타입이 더 크게 되어 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style11&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;할당되는 메모리 크기&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;데이터 표현 범위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;정수형&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;long&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;8 byte&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;-9,223,272,036,854,775,808 ~&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;9,223,272,036,854,775,807&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;실수형&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;float&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;4 byte&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;(3.4 X 10^-38) ~ (3.4 X 10^38)의 근사값&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4 byte의 float가 더 큰 수를 표현할 수 있는 가장 큰 이유는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;부동소수점 방식으로 표현&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부동소수점 방식에서는 지수부와 가수부를 나누고, 가수부에서는 실제 값을 지수부에는 제곱을 얼마나 곱할지 표현하기 때문에 표현 범위가 long 타입보다 더 커지게 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;char과 byte&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 도식화된 표현을 보면 char과 short가 동일선상에 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 char과 short 모두 2 byte의 크기를 갖고 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 char 타입은 기본형 타입의 문자형이지만 아스키 코드 숫자를 저장하기에 &lt;b&gt;사실상 정수형 타입&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아이러니하게도 1 byte인 바이트 타입은 2 byte인 char 타입으로 변환할 수가 없다. 왜냐하면 char 타입은 음수를 표현할 수 없기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, byte는 표현할 수 있는 데이터 표현 범위는 적지만 음수까지 표현하기 때문에, 음수를 표현할 수 없는 char에는 저장할 수 없다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;명시적 형변환&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;사용자가 타입 캐스트 연산자를 사용하여 어떤 자료형으로 선언된 변수를 다른 자료형으로 강제적으로 변환해주는 것을 의미한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강제 형변환으로 많이 불리우며, 묵시적 형변환과 비슷하지만 큰 데이터는 작은 데이터로 변환될 때 데이터 손실로 인해 자동 타입 변환을 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강제적인 동작이기 때문에 데이터의 손실이 일어난다면, 정확한 연산은 수행할 수 없기 때문에 예상치 못할 결과를 얻을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 코드처럼 명시적으로 작성을 해준다면 강제 형변환이 일어나게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6pTu1/dJMcabQoz1N/oNxuUm1EwCrTSNKxKpPcg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6pTu1/dJMcabQoz1N/oNxuUm1EwCrTSNKxKpPcg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6pTu1/dJMcabQoz1N/oNxuUm1EwCrTSNKxKpPcg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6pTu1%2FdJMcabQoz1N%2FoNxuUm1EwCrTSNKxKpPcg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;295&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드처럼 기본 자료형 중 boolean을 제외하면 모든 자료형은 명시적 형변환이 가능하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정수 -&amp;gt; 실수 형변환 주의점&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명시적 형변환 시 데이터 손실 외에도 정밀도 손실이라는 주의점이 존재한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;1168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF7aa4/dJMcabv6mAf/XH4lnghdglOD2IsJSVlkZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF7aa4/dJMcabv6mAf/XH4lnghdglOD2IsJSVlkZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF7aa4/dJMcabv6mAf/XH4lnghdglOD2IsJSVlkZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF7aa4%2FdJMcabv6mAf%2FXH4lnghdglOD2IsJSVlkZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1398&quot; height=&quot;1168&quot; data-origin-width=&quot;1398&quot; data-origin-height=&quot;1168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드 과정은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;int형 변수 num1, num2 생성 후 123456789 값 대입&lt;/li&gt;
&lt;li&gt;float형 변수에 num2 값 대입(묵시적 형변환)&lt;/li&gt;
&lt;li&gt;num2에 num3 값 대입(명시적 형변환)&lt;/li&gt;
&lt;li&gt;num1에 num2를 뺀 값 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머릿속으로 생각하면 분명 0이 나와야 할텐데, 왜 -3이 나오게 된 것일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 원인은 형변환에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int 값을 손실 없이 float로 변환하려면 가수 23 bit로 표현 가능한 값이어야 한다. 23 bit로 표현할 수 있는 최대값은 16,777,215이기 때문에 123,456,789는 &lt;u&gt;근사치로 변환&lt;/u&gt;된다. 이것이 바로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;정밀도 손실&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 float 값을 다시 int 값으로 변환할 때 num2에 처음 저장하였던 본래의 값을 가져올 수 없었던 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 정말 가져오고 싶다면 double을 사용하여 가수부에 52비트를 할당받아 변환시키면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;double과 float&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접에서 나오는 빈도 높은 질문들 중 형변환에 관한 질문이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;double형 변수 a1, a2에는 각각 1.1과 0.1이 담겨 있다. 이때 이 둘을 더했을 때 1.2이라는 결과에 대해 true인가? false인가?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두들 느낌상 false라는 것을 알겠지만 그 이유도 알고 있는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 통해 알아보자.&lt;/p&gt;
&lt;pre id=&quot;code_1767456393783&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

    public static void main(String[] args) {
        float a1 = 1.1F;
        float a2 = 0.1F;

        boolean a3 = a1 + a2 == 1.2F;
        System.out.println(&quot;a1과 a2의 값은 &quot; + (a1 + a2));
        System.out.println(a3 + &quot;\n&quot;);

        double b1 = 1.1;
        double b2 = 0.1;
        boolean b3 = b1 + b2 == 1.2;
        System.out.println(&quot;b1과 b2의 값은 &quot; + (b1 + b2));
        System.out.println(b3);
    }
}
/*
a1과 a2의 값은 1.2
true

b1과 b2의 값은 1.2000000000000002
false
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 실수형 타입은 기본적으로 double로 설정되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 float 변수에 소수를 대입하려면 'f'를 붙혀주거나, 명시적 형변환을 통해 double -&amp;gt; float로 강제 변환하여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 a1과 a2의 경우에는 true가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 '정확한 계산 결과다.&quot;가 아닌 &quot;&lt;b&gt;근사값이 우연히 같았다.&lt;/b&gt;&quot;가 맞는 표현이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부동소수점으로 값을 저장하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;float나 double은 10진수 소수를 이진수로 정확히 표현할 수 없어서 근사값으로 저장된다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt; 그래서 덧셈 결과도 근사값이 되어 정확도가 떨어지지만 이번 경우에 대해서는 연산 결과와 비교 대상이 같은 비트 대상으로 떨어져 true가 나온 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 다른 값의 조합이라면 false가 나올 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;double의 경우는 어떨까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;double는 가수부에 52비트를 할당받는다. 이는 가수부를 23비트 갖는 float 타입보다 정밀도가 높다는 것을 의미한다. 하지만 float 타입과 마찬가지로 10진수 소수를 정확히 표현하지 못하기 때문에&amp;nbsp;b1과 b2를 더했을 때, 1.2000000000000002가 출력되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면 float든 double이든 실수는 '정확한 결과'가 아닌 근사값이기 때문에 직접적인 비교는 가급적이면 피하고, 오차 허용 비교 개념으로 사용하는 것이 권장되는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1- &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%ED%83%80%EC%9E%85-%ED%98%95%EB%B3%80%ED%99%98-%EC%A2%85%EB%A5%98-%EB%B0%A9%EB%B2%95-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2- &lt;a href=&quot;https://backendcode.tistory.com/211#google_vignette&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;backendcode&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>java</category>
      <category>primitive type</category>
      <category>기본형</category>
      <category>명시적 형변환</category>
      <category>묵시적 형변환</category>
      <category>자바</category>
      <category>형변환</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/75</guid>
      <comments>https://gony-dev.tistory.com/75#entry75comment</comments>
      <pubDate>Sun, 4 Jan 2026 16:32:53 +0900</pubDate>
    </item>
    <item>
      <title>JAVA 기본형 데이터 타입</title>
      <link>https://gony-dev.tistory.com/74</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지난 시간에는 JAVA 데이터 자료형의 기본형 타입과 참조형 타입에 대해 각 종류와 특징에 대해 알아보았다.&lt;br /&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot;&gt;&lt;/span&gt;&lt;a style=&quot;letter-spacing: 0px; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif;&quot; href=&quot;https://gony-dev.tistory.com/73&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JAVA] - JAVA 변수 종류&lt;/a&gt;&lt;br /&gt;이번 시간에는 기본형 타입에 대해 더 자세히 알아보도록 하겠다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uJe0g/dJMcag5emla/PpLJwLDNSulzSiE7sjDXMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uJe0g/dJMcag5emla/PpLJwLDNSulzSiE7sjDXMK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uJe0g/dJMcag5emla/PpLJwLDNSulzSiE7sjDXMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuJe0g%2FdJMcag5emla%2FPpLJwLDNSulzSiE7sjDXMK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;163&quot; height=&quot;303&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1860&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 기본형 타입 - 정수형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 언어의 기본형 타입 중 정수형은 총 4가지로, byte, short, int, long이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int, long이 대부분 사용되며, byte, short는 나도 프로젝트에서 사용해 본 적이 거의 없다..&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 87px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style9&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 19px;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;기본값&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;할당되는 메모리 크기&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;데이터 표현 범위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px;&quot;&gt;byte&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;1 byte&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;-128 ~ 127&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px;&quot;&gt;short&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;2 byte&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;-32,768&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;~ 32,767&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px;&quot;&gt;int&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;4 byte&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;-2,147,483,648 ~ 2,147,483,647&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px;&quot;&gt;long&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%;&quot;&gt;0L&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;8 byte&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;-9,223,272,036,854,775,808 ~&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;9,223,272,036,854,775,807&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;long 변수에 값을 대입할 때는 int 자료형의 최대 크기보다 큰 경우, &lt;u&gt;'L'을 반드시 붙혀주어야 한다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'L'이 누락된다면, 컴파일 에러가 발생한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정수 오버플로우 / 언더플로우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 크기를 고려하지 않는다는 가정하에 정수형 데이터를 모두 long으로 치부해도 되겠지만, &lt;br /&gt;그렇지 않은 경우에 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;자신이 사용하고자 하는 데이터의 최소/최대 크기를 반드시 고려해야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 고려하지 않고 데이터를 저장하게 되면, 오버플로우/언더플로우가 발생하여 전혀 다른 값이 저장될 수 있기 때문이다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;오버플로우&lt;/b&gt; | 해당 타입이 표현할 수 있는 최대 표현 범위보다 큰 수를 저장할 때 발생하는 에러&lt;/li&gt;
&lt;li&gt;&lt;b&gt;언더플로우&lt;/b&gt; | 해당 타입이 표현할 수 있는 최소 표현 범위보다 작은 수를 저장할 때 발생하는 에러&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 코드를 통해 알아보자.&lt;/p&gt;
&lt;pre id=&quot;code_1767079237765&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

	public static void main(String[] args){
		
            byte max = (byte) 245;
            System.out.println(max);
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;byte 자료형의 데이터 표현 범위는 -128 ~ 127이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 max 변수에 32637을 저장한다면 크기 범위를 넘어서는 행위이기에 오버플로우가 발생하여 잘못된 결과가 저장된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2632&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kw1pk/dJMcagjQkVG/K2A6zc7bpRWpqmBqx8UvSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kw1pk/dJMcagjQkVG/K2A6zc7bpRWpqmBqx8UvSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kw1pk/dJMcagjQkVG/K2A6zc7bpRWpqmBqx8UvSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkw1pk%2FdJMcagjQkVG%2FK2A6zc7bpRWpqmBqx8UvSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;357&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2632&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2진수 / 8진수 / 16진수&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int 자료형은 10진수로 제공되지만 2진수, 8진수, 16진수로 변환하고 싶다면 다음과 같이 약속된 기호를 도입하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;1090&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwQzr2/dJMcaiIG66E/kuM2NQQL9iMhDwg6RI6ka1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwQzr2/dJMcaiIG66E/kuM2NQQL9iMhDwg6RI6ka1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwQzr2/dJMcaiIG66E/kuM2NQQL9iMhDwg6RI6ka1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwQzr2%2FdJMcaiIG66E%2FkuM2NQQL9iMhDwg6RI6ka1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;586&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;1090&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 기본형 타입 - 실수형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 실수 자료형은 float, double이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거에는 실수를 표현할 때 float를 많이 사용했지만, 기술의 발달로 메모리 공간이 증가하게 되면서 double형의 사용 빈도수가 늘어나 &lt;br /&gt;현재는 double형을 가장 많이 사용한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 91px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style9&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;할당되는 메모리 크기&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;데이터 표현 범위&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;literal 타입 접미사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;float&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;4 byte&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;(3.4 X 10^-38) ~ (3.4 X 10^38)의 근사값&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;F 또는 f&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;double&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;8 byte&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;(1.7 X 10^-308) ~ (1.7 X 10^308)의 근사값&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 36px;&quot;&gt;D 또는 d(생략 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실수의 표현 오차&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수형에도 표현할 수 있는 표현 범위가 제한되어 있듯이, 실수형에도 소숫점을 표현하는 범위가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소숫점은 경우에 따라 무수히 많은 숫자를 포함한 계산 결과를 제공한다. 이러한 한계를 최소화하기 위해서 컴퓨터는 소수를 이진법으로 표현할 때 고정 소수점 방식이 아닌 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;u&gt;&lt;b&gt;부동 소수점 방식&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(부동 소수점 방식은 소수점 위치를 고정하지 않고, 가수와 지수로 나누어 표현하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부동 소수점 방식을 사용하여 큰 범위의 실수까지도 표현이 가능하다는 장점이 있지만, 100% 정확하게 표현하는 것이 아니라서, 소수 연산 시 부정확한 실수의 계산값을 초래할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 문제에 대해 자바는 두 가지 방법을 제안한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;u&gt;실수를 int, long 정수형 타입으로 치환하여 계산&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;u&gt;BigDecimal 클래스 사용&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번의 경우에는 소수점의 실수들을 정수로 바꿀 만큼의 10의 n제곱 연산을 하여 나온 두 정수들을 연산한 후에 다시 실수형으로 되돌리는 방식이다.(ex. 12.34 + 23.45 (치환)-&amp;gt; 1234 + 2345 -&amp;gt; 3579 (다시 변환)-&amp;gt; 35.79)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번의 경우에는 소수의 크기가 9자리를 넘지 않으면 int를, 18자리를 넘지 않으면 long 타입을 사용하면 되지만 그 이상 넘어갈 경우에는 BigDecimal 클래스를 사용하여 표현 범위를 늘릴 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실수의 유효 자릿수&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실수의 유효 자릿수는 곧 &lt;b&gt;정밀도&lt;/b&gt;를 의미한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c02wXd/dJMcabQm028/NBCFnzSmXpaz3D6OomFmbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c02wXd/dJMcabQm028/NBCFnzSmXpaz3D6OomFmbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c02wXd/dJMcabQm028/NBCFnzSmXpaz3D6OomFmbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc02wXd%2FdJMcabQm028%2FNBCFnzSmXpaz3D6OomFmbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;379&quot; height=&quot;196&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 53px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;지수의 길이&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;가수의 길이&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;유효 자릿수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;float&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;8 bit&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;23 bit&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;소수점 약 6~7자리까지 높은 확률로 정확히 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;double&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;11 bit&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;52 bit&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;소수점 약 15~16자리까지 높은 확률로 정확히 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입에 따라 유효 자릿수가 달라지며, 이 &lt;u&gt;유효 자릿수는 좌측부터 시작되는 숫자 개수&lt;/u&gt;이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실수 오버플로우 / 언더플로우&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실수형에서도 정수형과 마찬가지로 오버플로우, 언더플로우가 발생할 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;오버플로우&lt;/b&gt; | 무한대&lt;/li&gt;
&lt;li&gt;&lt;b&gt;언더플로우&lt;/b&gt; | 양의 최소값보다 작은 값으로 0이 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 기본형 타입 - 논리형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2진수처럼 두 결과를 제공하는 논리형 자료형은 연산 결과에 대한 결과값이 제공된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진위를 가려내는 용도로 많이 사용되므로 if 연산자와 함께 종종 사용된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;1052&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbFXSO/dJMcagc5vcK/6jpsBDE2kpKtejO5kJcUIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbFXSO/dJMcagc5vcK/6jpsBDE2kpKtejO5kJcUIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbFXSO/dJMcagc5vcK/6jpsBDE2kpKtejO5kJcUIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbFXSO%2FdJMcagc5vcK%2F6jpsBDE2kpKtejO5kJcUIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;411&quot; height=&quot;365&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;1052&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 기본형 타입 - 문자형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;char형은 하나의 문자에 대한 자료형으로 사용된다.(문장이 아닌 문자 하나이다!)&lt;/p&gt;
&lt;pre id=&quot;code_1767084475953&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;char a = 'a';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 사용되며 주의할 점은 작은 따옴표를 사용해야 한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;큰 따옴표는 문장을 의미&lt;/u&gt;하므로 char에 사용한다면 에러가 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 위의 char형인 a는 문자 그대로 'a'를 출력하지만, 아스키코드나 유니코드를 통해서도 'a'를 출력할 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;아스키코드 | 1962년 &quot;ANSI&quot;가 정의한 미국 표준 정보교환 코드이며, 1963년 ASA에 의해 미국의 표준 부호가 됨.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;7비트의 이진수 조합으로 만들어져 총 129개의 부호 사용 가능&lt;/li&gt;
&lt;li&gt;아스키코드의 처음 32개는 프린터나 전송 제어용으로 사용되며, 나머지는 숫자와 로마 글자, 문장 기호를 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;유니코드 | 각 나라별 언어를 모두 표현하기 위해 나온 코드 체계
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;사용 중인 운영체제, 프로그램, 언어에 관계없이 문자마다 고유한 코드 값을 제공&lt;/li&gt;
&lt;li&gt;모든 문자를 16bit로 표현&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아스키코드와 유니코드&lt;/span&gt;&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKtpwI/dJMcadgjrDE/XvCIxTCi0RKfKNcF3JKHVK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKtpwI/dJMcadgjrDE/XvCIxTCi0RKfKNcF3JKHVK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKtpwI/dJMcadgjrDE/XvCIxTCi0RKfKNcF3JKHVK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cKtpwI/dJMcadgjrDE/XvCIxTCi0RKfKNcF3JKHVK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;488&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 문자열 자료형&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문장을 의미하는 자료형으로, char형이 작은 따옴표로 감쌌던 대신 문자열 자료형은 큰 따옴표로 감싼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 사용되는 String 클래스는 문자열을 위해 제공되었으며, &lt;u&gt;char[] 배열과 같은 동작 방식을 갖는다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;String 자료형을 이용하여 문자열 변수를 표현하는 방법은 두 가지가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1767155288959&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String str1 = &quot;Hello World!&quot;;
String str2 = new String(&quot;Hello World!&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 객체를 비교하였을 때, 이 둘은 같다고 말할 수 있을까? 정답은 &quot;아니다.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;str1은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;리터럴 표기 방식&lt;/b&gt;&lt;/span&gt;이며, JVM 내 힙 영역의 String Constant Pool에 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상수풀에 저장되기 때문에 같은 문자열 value를 가진다면 &lt;span style=&quot;color: #006dd7;&quot;&gt;재사용이 가능&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;str2는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;생성자 방식&lt;/b&gt;&lt;/span&gt;이며, str1과 마찬가지로 JVM 내 힙 영역의 String Constant Pool에 저장되고, &lt;br /&gt;&lt;u&gt;추가로 객체로 생성된다는 차이가 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 동일한 내용이라도 매번 새로운 객체가 생성된다. 이는 &lt;span style=&quot;color: #006dd7;&quot;&gt;메모리 사용의 증가로 이어지므로 리터럴 표기를 권장&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 String 인스턴스는 한 번 생성되면 변경할 수 없다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;불변 객체&lt;/b&gt;&lt;/span&gt;(Immutable Object)라고 불리며, 만약 자바에서 덧셈 연산자를 사용하여 문자열 결합을 수행하면, 기존 문자열의 내용이 변경되는 것이 아닌 내용이 합쳐진 새로운 String 인스턴스가 생성되게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1- &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B8%B0%EB%B3%B8-%EC%9E%90%EB%A3%8C%ED%98%95-%EC%A2%85%EB%A5%98-%EC%B4%9D%EC%A0%95%EB%A6%AC-int-double-char-String&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2- &lt;a href=&quot;https://velog.io/@hyeonseob22/java-String-%EB%A6%AC%ED%84%B0%EB%9F%B4-vs-%EC%83%9D%EC%84%B1%EC%9E%90-%EC%B0%A8%EC%9D%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;velog.io/@hyeonseob22&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>java</category>
      <category>Primitive</category>
      <category>기본형</category>
      <category>문자열</category>
      <category>자료형</category>
      <category>자바</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/74</guid>
      <comments>https://gony-dev.tistory.com/74#entry74comment</comments>
      <pubDate>Wed, 31 Dec 2025 15:00:10 +0900</pubDate>
    </item>
    <item>
      <title>JAVA 변수 종류</title>
      <link>https://gony-dev.tistory.com/73</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지난 시간에는 자바 소스 파일의 구성 요소들을 알아보았다.&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/72&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JAVA] - 자바 소스 코드 구조&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;이번 시간에는 자바 내에서 사용되는 변수의 타입과 차이를 알아보도록 하자.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xdf63/dJMcajnhur5/59nhncyLzEtXL0tDxb5yxK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xdf63/dJMcajnhur5/59nhncyLzEtXL0tDxb5yxK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xdf63/dJMcajnhur5/59nhncyLzEtXL0tDxb5yxK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxdf63%2FdJMcajnhur5%2F59nhncyLzEtXL0tDxb5yxK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;156&quot; height=&quot;290&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1860&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.&amp;nbsp; 변수(Variable)란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;'변수'&lt;/b&gt;는 데이터를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간&lt;/u&gt;이다.&lt;br /&gt;자바 언어에서도 변수를 사용하며 변수는 '데이터 타입'에 의해 그 목적이 정해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 타입(자료형)은 크게 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;기본형 타입&lt;/span&gt;&lt;/b&gt;과 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;참조형 타입&lt;/span&gt;&lt;/b&gt;으로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 기본형 타입(Primitive Type)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;u&gt;&lt;b&gt;기본형 타입&lt;/b&gt;은 계산을 위해 실제 값을 저장하는 타입을 의미&lt;/u&gt;&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 &lt;b&gt;논리형&lt;/b&gt;(boolean), &lt;b&gt;문자형&lt;/b&gt;(char), &lt;b&gt;정수형&lt;/b&gt;(byte, short, int, long), &lt;b&gt;실수형&lt;/b&gt;(float, double)으로 나뉜다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;837&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8xPBo/dJMcab3Umuu/Ee2GQQEakBQCk8X3lEx8c0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8xPBo/dJMcab3Umuu/Ee2GQQEakBQCk8X3lEx8c0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8xPBo/dJMcab3Umuu/Ee2GQQEakBQCk8X3lEx8c0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8xPBo%2FdJMcab3Umuu%2FEe2GQQEakBQCk8X3lEx8c0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;677&quot; height=&quot;345&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;837&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본형 타입은 비객체 타입으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;null이 될 수 없으며&lt;/b&gt;&lt;/span&gt;, &lt;u&gt;변수의 선언과 동시에 메모리가 생성된다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 후에 나올 참조형 타입과 다르게 모든 값은 메모리의 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;스택 영역에 저장&lt;/b&gt;&lt;/span&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 364px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style11&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;할당되는 메모리 크기&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;기본값&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;데이터 표현 범위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;논리형&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;boolean&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;false&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;true or false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;문자형&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;char&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;2 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;'\u0000'&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;0 ~ 65,535&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 182px;&quot; rowspan=&quot;4&quot;&gt;정수형&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;1 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;-128 ~ 127&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;short&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;2 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 26px;&quot;&gt;-32,768 ~ 32,767&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;int(default)&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;4 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;-2,147,483,648 ~ 2,147,483,647&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 78px;&quot;&gt;long&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 78px;&quot;&gt;8 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 78px;&quot;&gt;0L&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 78px;&quot;&gt;-9,223,272,036,854,775,808 ~&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;9,223,272,036,854,775,807&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 104px;&quot; rowspan=&quot;2&quot;&gt;실수형&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;float&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;4 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;0.0F&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;(3.4 X 10^-38) ~ (3.4 X 10^38)의 근사값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;double(default)&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;8 byte&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;0.0&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 52px;&quot;&gt;(1.7 X 10^-308) ~ (1.7 X 10^308)의 근사값&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 참조형 타입(Reference Type)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;참조형 타입&lt;/b&gt;은 객체의 주소를 저장하는 타입을 의미&lt;/span&gt;&lt;/u&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;null을 허용&lt;/b&gt;&lt;/span&gt;하며, 객체의 주소를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;클래스&lt;/b&gt;, &lt;b&gt;인터페이스&lt;/b&gt;, &lt;b&gt;배열&lt;/b&gt;, &lt;b&gt;enum&lt;/b&gt; 타입이 이에 해당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조형 타입은 기본형과는 달리 실제 값이 저장되지 않고, 자료가 저장된 공간의 주소를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;u&gt;JVM 내의 힙 영역에 실제 값을 저장하고, 그 참조값을 갖는 주소는 스택에 저장한다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;825&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vLcEB/dJMcajt28qZ/XaoDdKFbXBArStWWqhbkZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vLcEB/dJMcajt28qZ/XaoDdKFbXBArStWWqhbkZk/img.png&quot; data-alt=&quot;arr은 참조형 배열 타입으로 스택에 저장, 주소의 실제 값은 힙에 저장&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vLcEB/dJMcajt28qZ/XaoDdKFbXBArStWWqhbkZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvLcEB%2FdJMcajt28qZ%2FXaoDdKFbXBArStWWqhbkZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;371&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;825&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;arr은 참조형 배열 타입으로 스택에 저장, 주소의 실제 값은 힙에 저장&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 95px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style11&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;타입&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;기본값&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;할당되는 메모리 크기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;클래스&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;Null&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 76px;&quot; rowspan=&quot;4&quot;&gt;4 byte&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;인터페이스&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;Null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;열거&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;Null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;배열&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;Null&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &amp;nbsp;&lt;a href=&quot;https://velog.io/@minseojo/Java-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EA%B8%B0%EB%B3%B8%ED%98%95-%EC%B0%B8%EC%A1%B0%ED%98%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@minseojo/Java-데이터 타입-기본형-참조형&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EB%B3%80%EC%88%98%EC%9D%98-%EA%B8%B0%EB%B3%B8%ED%98%95-%EC%B0%B8%EC%A1%B0%ED%98%95-%ED%83%80%EC%9E%85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>java</category>
      <category>Primitive</category>
      <category>reference</category>
      <category>기본형</category>
      <category>변수</category>
      <category>자바</category>
      <category>참조형</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/73</guid>
      <comments>https://gony-dev.tistory.com/73#entry73comment</comments>
      <pubDate>Tue, 30 Dec 2025 17:18:18 +0900</pubDate>
    </item>
    <item>
      <title>자바 소스 코드 구조</title>
      <link>https://gony-dev.tistory.com/72</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;자바 문법을 이해하기 전에 자바 소스 코드가 어떻게 구성되어 있는지 알아보자.&lt;br /&gt;(자바 소스 코드는 JVM 컴파일러를 통해 바이트 코드로 컴파일링 되기 전의 상태이다.)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8WzSR/dJMcacIwh30/WODY4imwBGkcWdvgKX4Vo0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8WzSR/dJMcacIwh30/WODY4imwBGkcWdvgKX4Vo0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8WzSR/dJMcacIwh30/WODY4imwBGkcWdvgKX4Vo0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8WzSR%2FdJMcacIwh30%2FWODY4imwBGkcWdvgKX4Vo0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;149&quot; height=&quot;277&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1860&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;0. 시작하기 전에..&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바로 프로그래밍을 하기 위해서는 JDK라는 개발 도구가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS에 JDK를 설치하면 JVM과 JRE 등 자바 개발에 필요한 프로그램들이 설치된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해가 되지 않는다면 아래의 글을 참고해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/65&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.11.24 - [JVM] - JDK / JRE / JVM 개념&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1766938859754&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;JDK / JRE / JVM 개념&quot; data-og-description=&quot;Java 언어를 사용하여 프로젝트를 사용하는 것은 우리에게 기본적인 행위이지만어떤 식으로 돌아가는지 아는 이들은 과연 얼마나 될까?Java 프로그램이 돌아가게 하는 JDK와 JRE, 그리고 이 둘을 합&quot; data-og-host=&quot;gony-dev.tistory.com&quot; data-og-source-url=&quot;https://gony-dev.tistory.com/65&quot; data-og-url=&quot;https://gony-dev.tistory.com/65&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mLNy9/hyZPRbhQwR/KWN8b834Z6Vs711Rk2kvTK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/gPOKP/hyZQD4GBEF/RSlKYEVUrRCm5np7hYMaIK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bbNWEN/hyZQA1dLmU/0BdK3zRSqywpo5jn2cBVW1/img.png?width=1404&amp;amp;height=829&amp;amp;face=0_0_1404_829&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/65&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gony-dev.tistory.com/65&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mLNy9/hyZPRbhQwR/KWN8b834Z6Vs711Rk2kvTK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/gPOKP/hyZQD4GBEF/RSlKYEVUrRCm5np7hYMaIK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bbNWEN/hyZQA1dLmU/0BdK3zRSqywpo5jn2cBVW1/img.png?width=1404&amp;amp;height=829&amp;amp;face=0_0_1404_829');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;JDK / JRE / JVM 개념&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Java 언어를 사용하여 프로젝트를 사용하는 것은 우리에게 기본적인 행위이지만어떤 식으로 돌아가는지 아는 이들은 과연 얼마나 될까?Java 프로그램이 돌아가게 하는 JDK와 JRE, 그리고 이 둘을 합&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gony-dev.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 자바 소스 파일 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 모든 소스 코드는 class 안에 작성하도록 명시되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, &lt;u&gt;자바 프로그램은 많은 class의 집합으로 이루어져 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 일반적인 자바 소스 코드는 다음과 같은 형태로 구성되어 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1767014651826&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. 패키지 선언
package com.hello.helloworld

// 2. import 선언
import java.lang.*;

// 3. Class 선언
public class MyClass {

	// 4. main 메서드 선언
	public static void main(String[] args) {
    	String str = hello(&quot;Hello World!&quot;);
        System.out.println(str);
    }
    
    // 5. hello 메서드 선언
    public static String hello(String msg) {
    	return msg + &quot; My name is Park!&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-1. 패키지(package) 선언&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;패키지&lt;/b&gt;는 클래스가 위치한 경로&lt;/u&gt;를 의미하며, 하나의 패키지 안에는 여러 패키지가 존재할 수도 있고, 여러 클래스가 존재할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 명명 규칙에 대해서는 다음과 같다. 하지만 암묵적으로 규칙이 되어 있을 뿐, 무조건적으로 따를 강제적 제약은 아니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;패키지는 자바 소스 파일의 최상단에 선언해야하며, &lt;span style=&quot;color: #ee2323;&quot;&gt;두 번 이상 허용되지 않는다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;패키지명은 영어 대소문자를 모두 사용(=camel case)할 수 있으나, 대부분 &lt;span style=&quot;color: #ee2323;&quot;&gt;영어 소문자만으로 구성하는 것을 권장&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;동일한 이름의 클래스가 여러 존재하는 경우, 패키지를 기준으로 클래스를 구분할 수 있다.&lt;/li&gt;
&lt;li&gt;패키지는 OS 내의 폴더와 같이 물리적인 경로를 의미하며, 패키지 선언에 포함되는 '.'은 OS에서 폴더를 구분하는 '\'와 동일하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 규칙으로 서로 연관된 클래스들을 패키지 단위로 묶으면, 프로젝트 내 클래스들을 효율적으로 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-2. import 선언&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;'import'&lt;/b&gt;는 특정 클래스에서 다른 클래스를 참조하고 싶을 때 선언하는 키워드&lt;/u&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 코드에서 사용할 클래스 패키지에 대한 정보를 미리 제공하는 역할을 하며, 참조할 패키지에 대해서는 경로를 포함한 풀 네임을 명시해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 자바에서 import를 사용할 수 없다면(그럴 일은 없겠지만..), &lt;br /&gt;아래 코드처럼 String 클래스와 같이 클래스의 전체 경로를 선언하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1767016132213&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.hello.helloworld;

public class Hello {
	
    public static void main(String args[]){
    	java.lang.String str = hello(&quot;Hello World!&quot;);
        
    }
    
    public static java.lang.String hello(String msg){
    	return msg + &quot; My name is Park!&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 예시 코드로서 보여준 것이지만, java.lang 패키지에 대해서는 import문을 사용하지 않아도 클래스 이름만으로 사용할 수 있도록 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;u&gt;import를 선언할 때에는 주의할 점이 있는데, 선언 시 '*'를 사용하면 해당 패키지에 포함된 모든 클래스를 가져오지만 모든 하위 패키지의 클래스까지 포함시켜주지 않는다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 하위 클래스까지 가져오고 싶다면 직접 하위 도메인 경로를 지정해 표현하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-3. 클래스 선언&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;클래스&lt;/b&gt;는 객체를 정의해 둔 설계도로 정의&lt;/u&gt;할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 명은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;반드시 소스 파일명과 일치&lt;/b&gt;&lt;/span&gt;해야하며, 접근제어자에 따라 동일한 클래스명을 가질 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 MyClass 클래스명은 public으로 지정하여 다른 패키지 내에서 사용할 수 있기 때문에 중복 문제가 발생하지 않도록 하나만 존재해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 구성은 아래의 4가지로 구성되어 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;필드&lt;/b&gt; | 객체의 데이터를 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;생성자&lt;/b&gt; | 생성된 객체를 초기화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메서드&lt;/b&gt; | 객체의 동작을 실행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내부 클래스&lt;/b&gt; | 클래스나 인터페이스의 내부에 선언&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-4. main 메서드 선언&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 메서드는 프로그램을 실행하는 메인 스레드 역할을 하며 구성된 바는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1767019765255&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) {
	// psvm이라는 단축어로 메서드 자동 생성이 가능하다!
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;public | 모든 클래스에서 사용 가능한 의미의 접근 제어자&lt;/li&gt;
&lt;li&gt;static | 컴파일 시 가장 빠르게 정의되어 별도의 객체 생성 없이 모든 객체와 공유가 가능&lt;/li&gt;
&lt;li&gt;void | 반환값이 존재하지 않는 메서드&lt;/li&gt;
&lt;li&gt;main | 메서드명&lt;/li&gt;
&lt;li&gt;String[] args | 연속적인 문자열 데이터가 들어가는 저장 공간&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9E%90%EB%B0%94-%EC%86%8C%EC%8A%A4-%EC%BD%94%EB%93%9C-%EA%B5%AC%EC%A1%B0-%ED%95%9C%EB%88%88%EC%97%90-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa dev&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;a href=&quot;https://congsong.tistory.com/65&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Congsong&lt;/a&gt;&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>java</category>
      <category>소스 코드</category>
      <category>자바</category>
      <category>클래스</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/72</guid>
      <comments>https://gony-dev.tistory.com/72#entry72comment</comments>
      <pubDate>Mon, 29 Dec 2025 23:53:31 +0900</pubDate>
    </item>
    <item>
      <title>클래스 로드 및 초기화 시점</title>
      <link>https://gony-dev.tistory.com/71</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;지난 시간에는 JVM의 프로그램 상에서 작동하는 파라미터 전달 방법 두 가지의 차이를 알아보고,&lt;br /&gt;힙/스택 영역에서 어떻게 동작하는지 알아보았다.&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/70&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JVM] - Call by Value / Call by Reference&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;이번 시간에는 자바 클래스 파일들이 어느 시점에 로딩되고 초기화되는지 알아보도록 하자.&lt;br /&gt;출처 - &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%8A%94-%EC%96%B8%EC%A0%9C-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%97%90-%EB%A1%9C%EB%94%A9-%EC%B4%88%EA%B8%B0%ED%99%94-%EB%90%98%EB%8A%94%EA%B0%80-%E2%9D%93&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Class Loader&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드와 초기화라는 키워드를 듣고 &lt;u&gt;클래스 로더&lt;/u&gt;가 생각난다면 JVM에 대해 어느정도 이해를 하고 있다고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 로더는 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크하여 Runtime Data Area에 올리는 작업을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작 방식은 크게 3가지로 나뉜다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y2Ge8/dJMcagRBYqm/TNVkVltmCZN1LQQ8EPW8Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y2Ge8/dJMcagRBYqm/TNVkVltmCZN1LQQ8EPW8Wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y2Ge8/dJMcagRBYqm/TNVkVltmCZN1LQQ8EPW8Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy2Ge8%2FdJMcagRBYqm%2FTNVkVltmCZN1LQQ8EPW8Wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;202&quot; height=&quot;234&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Loading
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;클래스 파일들을 가져와 JVM의 메모리에 로드한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Linking
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Verifying - JVM 명세에 명시된 대로 작성되어 있는지 검증한다.&lt;/li&gt;
&lt;li&gt;Preparing - 클래스가 필요로 하는 메모리를 할당한다.&lt;/li&gt;
&lt;li&gt;Resolving - 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Initialization
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클래스 변수들을 적절한 값으로 초기화한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적으로 할당한다는 것이 클래스 로더에서 중요한 부분인데, &lt;br /&gt;Loading 과정은 모든 메모리를 한 번에 올리지 않고 필요한 경우 동적으로 메모리를 적재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 static 멤버들을 소스를 실행하자마자 한 번에 메모리에 올리게 될 경우 비효율적인 성능을 낼 수 있기 때문에 클래스 내의 멤버를 호출하게 되면 그때 클래스가 동적으로 메모리에 로드하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클래스 로딩 시점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 클래스를 JVM에 언제 로드할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 로딩 시점은 크게 3가지로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 클래스의 인스턴스가 생성될 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 클래스의 static 변수가 사용될 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 클래스의 static method가 호출될 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 경우들을 예제 코드로 하나씩 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 static 멤버를 로드 및 초기화하기 위해 준비한 Outer.class이다.&lt;/p&gt;
&lt;pre id=&quot;code_1766136742278&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Outer {

    // 일반 static 필드
    static String value = init(&quot;Outer.class&quot;, &quot;Outer static 필드&quot;);

    // 컴파일 타임 상수 (String literal): Method Area의 상수 풀로 인라인되어
    static final String CONST = &quot;Outer constant 필드&quot;;

    Outer() {
        log(&quot;Outer 생성자 초기화&quot;);
    }

    static void getInstance() {
        log(&quot;Outer.getInstance() 메서드 호출&quot;);
    }

    // ---- Holder ----
    static class Holder {

        // 클래스 변수
        static String value = &quot;Holder static 필드&quot;;

        // 상수
        static final String VALUE_CONST = &quot;Holder constant 필드&quot;;

        Holder() {
            log(&quot;Holder 생성자 초기화&quot;);
        }
    }

    // ---- Inner ----
    class Inner {
        Inner() {
            log(&quot;Inner 생성자 초기화&quot;);
        }
    }

    // ====== 관찰용 유틸 ======
    private static String init(String name, String v) {
        log(&quot;init field -&amp;gt; &quot; + name);
        return v;
    }

    private static void log(String msg) {
        // 어떤 ClassLoader로 로드됐는지까지 같이 출력
        System.out.printf(&quot;[%s] %s%n&quot;,
                Outer.class.getClassLoader(),
                msg
        );
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 로드의 동작을 자세히 관찰하기 위해서 두 가지 메서드를 추가하였다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;init
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;해당 객체가 어디로부터 초기화되었는지 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;log
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;어떤 클래스로더로 로더되었고, 어떤 동작을 나타내는지 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 아무것도 출력하지 않았을 경우&lt;/p&gt;
&lt;pre id=&quot;code_1766137002617&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

    public static void main(String[] args) {
        System.out.println(&quot;=== main start ===&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1718&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceN1sv/dJMcagKQIJt/xQi6b8VFSIHaJWAaqE3Qk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceN1sv/dJMcagKQIJt/xQi6b8VFSIHaJWAaqE3Qk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceN1sv/dJMcagKQIJt/xQi6b8VFSIHaJWAaqE3Qk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceN1sv%2FdJMcagKQIJt%2FxQi6b8VFSIHaJWAaqE3Qk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1718&quot; height=&quot;94&quot; data-origin-width=&quot;1718&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보는 바와 같이 MyClass만 로드되고 있는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Outer 클래스의 어떤 객체도 사용하지 않았기 때문에 Outer 클래스는 로드되지 않는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. static 변수 호출하기&lt;/p&gt;
&lt;pre id=&quot;code_1766137352925&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

    public static void main(String[] args) {
        System.out.println(&quot;=== main start ===&quot;);
        System.out.println(&quot;static 필드인 value 값은 &quot; + Outer.value + &quot;입니다.&quot;);
        System.out.println(&quot;=== main end ===&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxUn3p/dJMcahCYReg/YBowVyUcTRYUAD8xQiplq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxUn3p/dJMcahCYReg/YBowVyUcTRYUAD8xQiplq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxUn3p/dJMcahCYReg/YBowVyUcTRYUAD8xQiplq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxUn3p%2FdJMcahCYReg%2FYBowVyUcTRYUAD8xQiplq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1722&quot; height=&quot;266&quot; data-origin-width=&quot;1722&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pWvMp/dJMcaaDRvj1/9w5teW8YEMNZBQ0nVvRss0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pWvMp/dJMcaaDRvj1/9w5teW8YEMNZBQ0nVvRss0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pWvMp/dJMcaaDRvj1/9w5teW8YEMNZBQ0nVvRss0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpWvMp%2FdJMcaaDRvj1%2F9w5teW8YEMNZBQ0nVvRss0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1444&quot; height=&quot;40&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;40&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1744&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tc16P/dJMcacuUYaJ/Czcmr1SK2objXy30vW2JFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tc16P/dJMcacuUYaJ/Czcmr1SK2objXy30vW2JFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tc16P/dJMcacuUYaJ/Czcmr1SK2objXy30vW2JFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftc16P%2FdJMcacuUYaJ%2FCzcmr1SK2objXy30vW2JFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1744&quot; height=&quot;86&quot; data-origin-width=&quot;1744&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 메서드가 실행되자 MyClass를 할당하고 Outer 클래스가 로드되어 static 필드를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. static final 상수 호출하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static final 필드의 값은 과연 Outer 클래스를 로드할까?&lt;/p&gt;
&lt;pre id=&quot;code_1766389609425&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

    public static void main(String[] args) {
        System.out.println(&quot;=== main start ===&quot;);
        System.out.println(&quot;static final 상수 CONST는 &quot; + Outer.CONST + &quot;입니다.&quot;);
        System.out.println(&quot;=== main end ===&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/59UDf/dJMcagxkdul/K2ns0FmCR8WbRkm97GmkEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/59UDf/dJMcagxkdul/K2ns0FmCR8WbRkm97GmkEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/59UDf/dJMcagxkdul/K2ns0FmCR8WbRkm97GmkEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F59UDf%2FdJMcagxkdul%2FK2ns0FmCR8WbRkm97GmkEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1756&quot; height=&quot;308&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상했겠지만 Outer Class를 로드하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static final과 같이 선언된 상수는 JVM의 Method Area의 Constant Pool에 따로 저장되어 관리되기 때문이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 내부 클래스 / static 메서드 호출&lt;/p&gt;
&lt;pre id=&quot;code_1766389737652&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

    public static void main(String[] args) {
        System.out.println(&quot;=== main start ===&quot;);
        Outer.getInstance();
        new Outer().new Inner();
        System.out.println(&quot;=== main end ===&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1720&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzdaz/dJMb99SvTz5/FJBUWrl0Qa89vPGgjhT9Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzdaz/dJMb99SvTz5/FJBUWrl0Qa89vPGgjhT9Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzdaz/dJMb99SvTz5/FJBUWrl0Qa89vPGgjhT9Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkzdaz%2FdJMb99SvTz5%2FFJBUWrl0Qa89vPGgjhT9Ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1720&quot; height=&quot;176&quot; data-origin-width=&quot;1720&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2144&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMkXL4/dJMcahbVVww/XP27CbE18t2bDJUa4UHJSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMkXL4/dJMcahbVVww/XP27CbE18t2bDJUa4UHJSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMkXL4/dJMcahbVVww/XP27CbE18t2bDJUa4UHJSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMkXL4%2FdJMcahbVVww%2FXP27CbE18t2bDJUa4UHJSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2144&quot; height=&quot;134&quot; data-origin-width=&quot;2144&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAxiT/dJMb99523g9/pl4PNB7QLE8GxmZD766IlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAxiT/dJMb99523g9/pl4PNB7QLE8GxmZD766IlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAxiT/dJMb99523g9/pl4PNB7QLE8GxmZD766IlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAxiT%2FdJMb99523g9%2Fpl4PNB7QLE8GxmZD766IlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1796&quot; height=&quot;134&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 Outer의 static 메서드와 Outer의 내부 클래스를 각각 선언했을 때의 결과이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;getInstance()의 경우에는 Outer 클래스만 로드하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Outer 클래스의 내부 클래스인 Inner 클래스를 생성할 때는 Outer과 Inner 클래스 모두 로드가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 로드가 되기 때문에 Inner 클래스에 static을 설정하지 않는다면 메모리 누수가 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클래스 초기화 시점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 초기화는 static에 대한 필드 및 메서드의 값을 할당하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 로더는 클래스 초기화 과정을 3단계로 나누어져 있지만, &lt;br /&gt;클래스 초기화는 클래스 로드 시점과 거의 동일하게 일어남을 위의 예시 코드를 통해 알 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 로더에 대한 단계를 설명하기 위해 기술되어 있었지만 거의 로드와 초기화는 거의 동시에 진행되었다고 보면 된다.&lt;/p&gt;</description>
      <category>JVM</category>
      <category>ClassLoader</category>
      <category>java</category>
      <category>jvm</category>
      <category>로드</category>
      <category>자바</category>
      <category>초기화</category>
      <category>클래스로더</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/71</guid>
      <comments>https://gony-dev.tistory.com/71#entry71comment</comments>
      <pubDate>Mon, 22 Dec 2025 18:04:06 +0900</pubDate>
    </item>
    <item>
      <title>Call by Value / Call by Reference</title>
      <link>https://gony-dev.tistory.com/70</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;지난 시간에는 JVM 내에서 사용되는 메모리 영역들인&lt;br /&gt;Method Area, Heap Area, Stack Area를 알아보았다.&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gony-dev.tistory.com/69&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[JVM] - 자바 코드의 메모리 영역&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;이번 시간에는 Java의 Call by Value와 Call by Reference에 대해 알아보자.&lt;br /&gt;출처 - &lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9E%90%EB%B0%94%EB%8A%94-Call-by-reference-%EA%B0%9C%EB%85%90%EC%9D%B4-%EC%97%86%EB%8B%A4-%E2%9D%93#thankYou&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Inpa Dev&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Java의 Call by Value / Call by Reference&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바에서 메서드를 호출할 때 파라미터를 전달하는 방법에는 두 가지가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;Call by Value&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;Call by Reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 프로그래밍 시 반드시 마주하게 되는 개념으로 함수의 매개변수에서 값을 복사하느냐 주소값을 참조하느냐에 따라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반환 결과가 달라지기 때문에 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터형에 따라 동작 차이가 나는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 데이터형을 먼저 알아보면 크게 두 가지로 나뉜다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;u&gt;기본형&lt;/u&gt;(Primitive Type)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Boolean Type - boolean&lt;/li&gt;
&lt;li&gt;Nemuric Tyep - int, short, long, double, char&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;u&gt;참조형&lt;/u&gt;(Reference Type)
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Class Type, Interface Type, Array Type, Enum Type&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 코드로 진행해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1765440118259&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MyClass {

	public static void main(String[] args){
    	
        int num = 0;
        int[] arr = { 0 };
        
        add_num(num);
        add_arr(arr);
        
        System.out.println(&quot;num의 값은 &quot; + num + &quot;입니다.&quot;);
        System.out.println(&quot;arr[0]의 값은 &quot; + arr[0] + &quot;입니다.&quot;);
    }
    
    static void add_num(int num){
    	
        num += 100;
    }
    
    static void add_arr(int[] array){
    	
        array[0] += 100;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드의 출력 결과는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1765440162166&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;num의 값은 0입니다.
arr[0]의 값은 100입니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 처리 결과가 바로 Call by Value와 Call by Reference가 일어난 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. Call by Value&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Call by Value는 메서드를 호출할 때 값을 넘겨주기 때문에 Pass by Value라고도 불린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;메서드를 호출하는 호출자의 변수와 호출 당하는 수신자의 파라미터는 복사된 서로 다른 변수&lt;/b&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 &lt;u&gt;&lt;b&gt;값만 전달하기 때문에 수신자의 파라미터를 수정해도 호출자의 변수에는 아무런 영향이 없다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Call by Reference&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;Call by Reference&lt;/b&gt;&lt;/u&gt;&lt;b&gt;는 주소를 직접 넘기기 때문에 호출자의 변수와 수신자의 파라미터는 완전히 동일한 변수&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 메서드 내에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;파라미터를 수정하면 그대로 원본 변수에도 적용이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 다시 살펴보며 알아보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 num 변수는 Primitive Type이고, arr 배열 변수는 Reference Type으로 선언된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;arr 배열 변수의 실제 데이터는 heap 영역에 저장되어 이를 참조할 주소값을 지니게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/66zmt/dJMcafkPchk/FJMOSRZVtRsVcBr01En5Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/66zmt/dJMcafkPchk/FJMOSRZVtRsVcBr01En5Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/66zmt/dJMcafkPchk/FJMOSRZVtRsVcBr01En5Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F66zmt%2FdJMcafkPchk%2FFJMOSRZVtRsVcBr01En5Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;563&quot; height=&quot;407&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후에 add_num 메서드를 호출하면 add_num의 스택 프레임이 생성되며 메서드 내의 지역 변수 num에 100을 더하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 add_num 스택 프레임 내에 있는 지역 변수 num의 값이 바뀐 것이지 main 스택 프레임 내의 num의 값이 바뀐 것이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매개변수인 num은 그저 main의 num으로부터 원시값을 복사하여 받았기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 바로 call by value이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해 add_num의 지역 변수인 num과 main의 num은 상관없는 &lt;u&gt;별개의 객체&lt;/u&gt;라는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;arr에 대한 경우는 다르다.&lt;br /&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;add_arr을 호출하는데 같은 방식으로 add_arr 스택 프레임이 생성되고 매개변수인 array가 생성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;add_num처럼 변수의 값이 복사되어 파라미터에 넘겨지게 되는데, 이때 arr 변수가 들고있는 값은 '원시값'이 아닌 '주소값'이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;즉, arr의 주소값이 매개변수로 넘겨지게 되어 add_arr에서의 값 변경은 힙 영역의 주소 참조 데이터를 변경하게 되는것이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Call by Reference 개념이 없는 Java&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwKiDS/dJMcagD4fRZ/Lny8Q0E96YjknPsGAnbVV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwKiDS/dJMcagD4fRZ/Lny8Q0E96YjknPsGAnbVV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwKiDS/dJMcagD4fRZ/Lny8Q0E96YjknPsGAnbVV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwKiDS%2FdJMcagD4fRZ%2FLny8Q0E96YjknPsGAnbVV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;280&quot; height=&quot;206&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 자바 프로그래밍에서는 call by reference가 존재하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 C 언어와 달리 &lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;u&gt;포인터를 숨겨 개발자가 직접 메모리 주소에 접근하지 못하게 막아놓았기 때문&lt;/u&gt;&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C언어는 '*' 과 '&amp;amp;' 기호를 통해 주소 접근이 가능하다!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 프로그래밍은 매개변수의 복사된 값에 따라 동적으로 연산을 수행한다고 보면 된다.&lt;/p&gt;</description>
      <category>JVM</category>
      <category>Call by reference</category>
      <category>Call by value</category>
      <category>java</category>
      <category>자바</category>
      <category>포인터</category>
      <category>힙 영역</category>
      <author>minarinamu</author>
      <guid isPermaLink="true">https://gony-dev.tistory.com/70</guid>
      <comments>https://gony-dev.tistory.com/70#entry70comment</comments>
      <pubDate>Sun, 14 Dec 2025 23:02:21 +0900</pubDate>
    </item>
  </channel>
</rss>