René's URL Explorer Experiment


Title: 아이템 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 - Fin · Issue #210 · Study-2-Effective-Java/Effective-Java · GitHub

Open Graph Title: 아이템 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 - Fin · Issue #210 · Study-2-Effective-Java/Effective-Java

X Title: 아이템 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 - Fin · Issue #210 · Study-2-Effective-Java/Effective-Java

Description: Discussed in https://github.com/orgs/Study-2-Effective-Java/discussions/204 Originally posted by bunsung92 April 10, 2023 0. TL;DR 📚 불변식을 지키기 위해 인스턴스를 통제한다면, 열거 타입을 이용하자. 직렬화와 인스턴스 통제가 모두 필요하면 readResolve() 작성하고, 클래스의 모든 참조 타입 인스턴스 필드를 t...

Open Graph Description: Discussed in https://github.com/orgs/Study-2-Effective-Java/discussions/204 Originally posted by bunsung92 April 10, 2023 0. TL;DR 📚 불변식을 지키기 위해 인스턴스를 통제한다면, 열거 타입을 이용하자. 직렬화와 인스턴스 통제가 모두 필요하면 read...

X Description: Discussed in https://github.com/orgs/Study-2-Effective-Java/discussions/204 Originally posted by bunsung92 April 10, 2023 0. TL;DR 📚 불변식을 지키기 위해 인스턴스를 통제한다면, 열거 타입을 이용하자. 직렬화와 인스턴스 통제가 모두 필요하면 read...

Opengraph URL: https://github.com/Study-2-Effective-Java/Effective-Java/issues/210

X: @github

direct link

Domain: patch-diff.githubusercontent.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"아이템 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 - Fin","articleBody":"### Discussed in https://github.com/orgs/Study-2-Effective-Java/discussions/204\r\n\r\n\u003cdiv type='discussions-op-text'\u003e\r\n\r\n\u003csup\u003eOriginally posted by **bunsung92** April 10, 2023\u003c/sup\u003e\r\n# 0. TL;DR 📚\r\n\r\n- 불변식을 지키기 위해 인스턴스를 통제한다면, 열거 타입을 이용하자.\r\n- 직렬화와 인스턴스 통제가 모두 필요하면 `readResolve()` 작성하고, 클래스의 모든 참조 타입 인스턴스 필드를 `transient` 키워드를 이용하자.\r\n\r\n---\r\n\r\n# 1. 인스턴스 수의 통제\r\n\r\n인스턴스 수를 통제하는 기법은 바로 `싱글턴`이다.\r\n그리고 `직렬화`와 `싱글턴`은 상성이 맞지 않다.\r\n\r\n바로 `implement Serializable` 을 추가하는 순간 싱글턴이 아니게 되기 때문이다.\r\n기본 직렬화를 쓰지 않더라도 (아이템 87) \r\n명시적인 `readObject()` (아이템88) 를 제공하더라도 소용없다.\r\n\r\n어떤 `readObject()`를 사용하든 이 클래스가 초기화될 때 만들어진 인스턴스와는 별개의 인스턴스를 반환하기 때문이다.\r\n\r\n![image](https://user-images.githubusercontent.com/53285909/233821822-853eae70-ffdf-4609-9c7b-d8578314d836.png)\r\n\r\n---\r\n\r\n# 2. readResolve()\r\n\r\n`readObject()` 가 별개의 인스턴스를 반환하기만을 마냥 기다릴 수 없다.\r\n`readResolve()`를 가용하여 필연적으로 원본의 Instance를 반환하게 지시할 수 있다.\r\n\r\n``` java\r\npublic class Foo {\r\n\tprivate static final Foo INSTANCE = new Foo();\r\n\r\n\tprivate Foo() {\r\n\t}\r\n\r\n\tpublic static Foo getINSTANCE() {\r\n\t\treturn INSTANCE;\r\n\t}\r\n\r\n        // readResolve 메서드를 정의한다.\r\n\tprivate Object readResolve() {\r\n        // 싱글턴을 보장하기 위함!\r\n\t\treturn INSTANCE;\r\n\t}\r\n}\r\n```\r\n\r\n이때 만약에 싱글턴 클래스의 필드가 존재한다면, 해당 필드는 반드시 모두다 `transient` 키워드를 추가해야한다.\r\n`readResolve()`가 수행되기전에 역 직렬화된 객체의 참조를 공격할 여지가 남는다.\r\n\r\n## 2.1 deep To `readResolve()`\r\n\r\n- readObject()는 ObjectInputStream클래스 의 기존 메서드임.\r\n- 역직렬화 readObject()메서드는 역직렬화 중인 개체에 readResolve()메서드가 구현되어 있는지 여부를 내부적으로 확인함. \r\n- 메소드가 존재 하면 readResolve()호출됨.\r\n\r\n\u003e 즉 구현 여부를 판단하여 `readResolve()` 를 호출하기 전에 어떤 동작을 해버리면 막기 어려워진단 말임!\r\n\r\n[readResolve()와 도둑 클래스](https://donghyeon.dev/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C%EC%9E%90%EB%B0%94/2021/11/12/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%88%98%EB%A5%BC-%ED%86%B5%EC%A0%9C%ED%95%B4%EC%95%BC-%ED%95%9C%EB%8B%A4%EB%A9%B4-readResolve-%EB%B3%B4%EB%8B%A4%EB%8A%94-%EC%97%B4%EA%B1%B0-%ED%83%80%EC%9E%85%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EC%9E%90/)\r\n\r\n---\r\n\r\n# 3. 싱글턴과 열거 타입\r\n\r\n- 직렬화 가능한 인스턴스 통제 클래스를 열거 타입을 이용해 구현하면, 선언한 상수 외의 다른 객체가 존재하지 않는다는것을 `자바`가 보증한다.\r\n  - 하지만 `native 코드`까지 조작한다면 이는 완전하지 않을 수 있다.\r\n\r\n- readResolve()는 완전히 쓸모 없어진것이 아니다. \r\n  - 직렬화 가능 인스턴스 통제 클래스를 작성해야 하는데, 컴파일에는 어떤 인스턴스들이 있는지 알 수 없는 상황이라면, 열거타입으로 표현하는 것이 불가능하기 때문이다.\r\n\r\n## 3.1 readResolve()와 접근제어자\r\n\r\n- final Class 에서는 readResolve()는 private으로 선언해야한다.\r\n- final Class가 아닌 경우에는 package-private, protected, public으로 해당 메서드를 정의 할 수 있는데 이때 주의 할 점이있다.\r\n\r\n\u003e 하위 클래스에서 readResolve()를 재정의 하지 않고 형 변환을 통해 해당 직렬화를 이용 했다면, `ClassCastException` 이 발생한다.\r\n\r\n정리하자면 반드시 하위 클래스에서는 readResolve()를 정의해야 한다는 것이다!\r\n\r\n---\r\n\r\n# 4. 핵심 정리 📚\r\n\r\n- 내가 커스텀 직렬화를 하고 있고, 싱글턴 인스턴스를 보장 해야한다면, 두가지 선택권이 있다는걸 인지하자.\r\n\r\n```\r\n1. readResolve()\r\n2. 열거타입\r\n```\r\n\r\n- 반드시 1이 좋고, 2가 좋다. 보다는 각 상황에 알맞게 사용하도록 하자.\r\n- 고려할 사항은 열거 타입이 `readResolve()`보다 적다.\r\n\r\n---\r\n\r\n# 5. 회고 🧹\r\n\r\n2023-04-23 (일)\r\n\r\n- 해당 아이템의 회고보다 마지막 회고는 시점에 대한 느낌을 남기고 싶다.\r\n- 마지막 아이템을 맡아 마지막 정리를 하게 되었고, 자바의 여러 재미를 알아 볼 수 있어서 좋았던 것 같다.\r\n- 언젠간 다시 이 페이지로 돌아와, 우리 7인의 노고를 다시 보게 된다면, 이 시점에 우린 이렇게 살고 있었구나 느낄 수 있는 작은 발자취가 되었다고 생각한다.\r\n\r\n---\r\n\r\n\u003e 참조 자료\r\n\u003e \u003e https://madplay.github.io/post/what-is-readresolve-method-and-writereplace-method\r\n\u003e \u003e https://stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolve\r\n\u003e \u003e https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0\u003c/div\u003e","author":{"url":"https://github.com/Irisation23","@type":"Person","name":"Irisation23"},"datePublished":"2023-04-23T07:13:28.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/210/Effective-Java/issues/210"}

route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:a38175c8-35b2-d494-6e1a-1286ca39870e
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-id931A:179CB9:9203900:C09E60B:696DFB4F
html-safe-nonce0d155e08b21468fa6bdab255661954c4ac765ce9956096026f3efe757cdeab0e
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5MzFBOjE3OUNCOTo5MjAzOTAwOkMwOUU2MEI6Njk2REZCNEYiLCJ2aXNpdG9yX2lkIjoiODA4MDY5MDkyNTc1NjM0OTI2MyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmaca751cd766141e44359fc9da3fe9c6d0f12a589c3de2c1af12b8b4b605b9e7c6e
hovercard-subject-tagissue:1679896999
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/Study-2-Effective-Java/Effective-Java/210/issue_layout
twitter:imagehttps://opengraph.githubassets.com/77b72737240310d68b3bdb2d935b9677651abb8c8660e011ab8a849b83af35fa/Study-2-Effective-Java/Effective-Java/issues/210
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/77b72737240310d68b3bdb2d935b9677651abb8c8660e011ab8a849b83af35fa/Study-2-Effective-Java/Effective-Java/issues/210
og:image:altDiscussed in https://github.com/orgs/Study-2-Effective-Java/discussions/204 Originally posted by bunsung92 April 10, 2023 0. TL;DR 📚 불변식을 지키기 위해 인스턴스를 통제한다면, 열거 타입을 이용하자. 직렬화와 인스턴스 통제가 모두 필요하면 read...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernameIrisation23
hostnamegithub.com
expected-hostnamegithub.com
None4922b452d03cd8dbce479d866a11bc25b59ef6ee2da23aa9b0ddefa6bd4d0064
turbo-cache-controlno-preview
go-importgithub.com/Study-2-Effective-Java/Effective-Java git https://github.com/Study-2-Effective-Java/Effective-Java.git
octolytics-dimension-user_id120388640
octolytics-dimension-user_loginStudy-2-Effective-Java
octolytics-dimension-repository_id577325341
octolytics-dimension-repository_nwoStudy-2-Effective-Java/Effective-Java
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id577325341
octolytics-dimension-repository_network_root_nwoStudy-2-Effective-Java/Effective-Java
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release7e5ae23c70136152637ceee8d6faceb35596ec46
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues/210#start-of-content
https://patch-diff.githubusercontent.com/
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2FStudy-2-Effective-Java%2FEffective-Java%2Fissues%2F210
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2FStudy-2-Effective-Java%2FEffective-Java%2Fissues%2F210
Sign up https://patch-diff.githubusercontent.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=Study-2-Effective-Java%2FEffective-Java
Reloadhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues/210
Reloadhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues/210
Reloadhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues/210
Study-2-Effective-Java https://patch-diff.githubusercontent.com/Study-2-Effective-Java
Effective-Javahttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java
Notifications https://patch-diff.githubusercontent.com/login?return_to=%2FStudy-2-Effective-Java%2FEffective-Java
Fork 3 https://patch-diff.githubusercontent.com/login?return_to=%2FStudy-2-Effective-Java%2FEffective-Java
Star 8 https://patch-diff.githubusercontent.com/login?return_to=%2FStudy-2-Effective-Java%2FEffective-Java
Code https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java
Issues 59 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues
Pull requests 0 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/pulls
Discussions https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions
Actions https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/actions
Projects 0 https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/projects
Security Uh oh! There was an error while loading. Please reload this page. https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/security
Please reload this pagehttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues/210
Insights https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/pulse
Code https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java
Issues https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues
Pull requests https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/pulls
Discussions https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/discussions
Actions https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/actions
Projects https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/projects
Security https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/security
Insights https://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/pulse
New issuehttps://patch-diff.githubusercontent.com/login?return_to=https://github.com/Study-2-Effective-Java/Effective-Java/issues/210
New issuehttps://patch-diff.githubusercontent.com/login?return_to=https://github.com/Study-2-Effective-Java/Effective-Java/issues/210
아이템 89. 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라 - Finhttps://patch-diff.githubusercontent.com/Study-2-Effective-Java/Effective-Java/issues/210#top
https://patch-diff.githubusercontent.com/Irisation23
12장 직렬화이펙티브 자바 12장 (직렬화)https://github.com/Study-2-Effective-Java/Effective-Java/issues?q=state%3Aopen%20label%3A%2212%EC%9E%A5%20%EC%A7%81%EB%A0%AC%ED%99%94%22
https://github.com/Irisation23
https://github.com/Irisation23
Irisation23https://github.com/Irisation23
on Apr 23, 2023https://github.com/Study-2-Effective-Java/Effective-Java/issues/210#issue-1679896999
https://github.com/orgs/Study-2-Effective-Java/discussions/204https://github.com/orgs/Study-2-Effective-Java/discussions/204
https://user-images.githubusercontent.com/53285909/233821822-853eae70-ffdf-4609-9c7b-d8578314d836.png
readResolve()와 도둑 클래스https://donghyeon.dev/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C%EC%9E%90%EB%B0%94/2021/11/12/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4-%EC%88%98%EB%A5%BC-%ED%86%B5%EC%A0%9C%ED%95%B4%EC%95%BC-%ED%95%9C%EB%8B%A4%EB%A9%B4-readResolve-%EB%B3%B4%EB%8B%A4%EB%8A%94-%EC%97%B4%EA%B1%B0-%ED%83%80%EC%9E%85%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EC%9E%90/
https://madplay.github.io/post/what-is-readresolve-method-and-writereplace-methodhttps://madplay.github.io/post/what-is-readresolve-method-and-writereplace-method
https://stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolvehttps://stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolve
https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0
Irisation23https://patch-diff.githubusercontent.com/Irisation23
12장 직렬화이펙티브 자바 12장 (직렬화)https://github.com/Study-2-Effective-Java/Effective-Java/issues?q=state%3Aopen%20label%3A%2212%EC%9E%A5%20%EC%A7%81%EB%A0%AC%ED%99%94%22
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.