Java에 임시 필드가 있는 이유는 무엇입니까?
질문자 :Animesh
Java의 transient
키워드는 필드가 직렬화(파일과 같이 저장됨을 의미) 프로세스의 일부가 아니어야 함을 나타내는 데 사용됩니다.
Java 언어 사양, Java SE 7 Edition , 섹션 8.3.1.3. transient
필드 :
transient
것으로 표시되어 개체의 영구 상태에 속하지 않음을 나타낼 수 있습니다.
예를 들어, 다른 필드에서 파생된 필드가 있을 수 있으며 직렬화를 통해 상태를 유지하는 대신 프로그래밍 방식으로만 수행해야 합니다.
다음은 이미지와 이미지에서 파생된 축소판을 포함하는 GalleryImage
class GalleryImage implements Serializable { private Image image; private transient Image thumbnailImage; private void generateThumbnail() { // Generate thumbnail. } private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException { inputStream.defaultReadObject(); generateThumbnail(); } }
이 예에서 thumbnailImage
generateThumbnail
메소드를 호출하여 생성된 축소판 이미지입니다.
thumbnailImage
필드는 transient
으로 표시되므로 원본 이미지와 축소판 이미지를 모두 유지하는 대신 image
즉, 직렬화된 개체를 저장하는 데 필요한 저장소가 줄어듭니다. (물론 이것은 시스템의 요구 사항에 따라 바람직할 수도 있고 바람직하지 않을 수도 있습니다. 이것은 단지 예일 뿐입니다.)
역직렬화 시 readObject
메서드가 호출되어 개체의 상태를 직렬화가 발생한 상태로 복원하는 데 필요한 모든 작업을 수행합니다. 그렇게 여기에, 썸네일 필요가 생성 될 readObject
메소드는 썸네일이 호출에 의해 생성 된 조치 할 수 있도록 재정의 generateThumbnail
방법을.
추가 정보는 Discover the secrets of the Java Serialization API (이는 원래 Sun Developer Network에서 제공됨) 문서에 특정 필드의 직렬화를 방지하기 위해 transient
키워드가 사용되는 시나리오를 제시하고 사용에 대해 설명하는 섹션이 있습니다.
coobird
transient
키워드를 이해하기 전에 직렬화의 개념을 이해해야 합니다. 독자가 직렬화에 대해 알고 있다면 첫 번째 요점을 건너뛰십시오.
직렬화란 무엇입니까?
직렬화는 객체의 상태를 영구적으로 만드는 프로세스입니다. 이는 개체의 상태가 유지(예: 파일에 바이트 저장) 또는 전송(예: 네트워크를 통해 바이트 전송)에 사용되는 바이트 스트림으로 변환됨을 의미합니다. 같은 방식으로 역직렬화를 사용하여 바이트에서 개체의 상태를 다시 가져올 수 있습니다. 직렬화는 네트워킹 프로그래밍에서 주로 사용되기 때문에 이것은 Java 프로그래밍에서 중요한 개념 중 하나입니다. 네트워크를 통해 전송해야 하는 객체는 바이트로 변환되어야 합니다. 이를 위해 모든 클래스 또는 인터페이스는 Serializable
인터페이스를 구현해야 합니다. 메소드가 없는 마커 인터페이스입니다.
이제 transient
키워드와 그 목적은 무엇입니까?
기본적으로 객체의 모든 변수는 영구 상태로 변환됩니다. 어떤 경우에는 해당 변수를 유지할 필요가 없기 때문에 일부 변수를 유지하지 않으려는 경우가 있습니다. transient
로 선언할 수 있습니다. 변수가 transient
로 선언되면 지속되지 않습니다. transient
키워드의 주요 목적입니다.
위의 두 가지 점을 다음 예를 통해 설명하고 싶습니다( 이 기사 에서 가져옴).
package javabeat.samples; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class NameStore implements Serializable{ private String firstName; private transient String middleName; private String lastName; public NameStore (String fName, String mName, String lName){ this.firstName = fName; this.middleName = mName; this.lastName = lName; } public String toString(){ StringBuffer sb = new StringBuffer(40); sb.append("First Name : "); sb.append(this.firstName); sb.append("Middle Name : "); sb.append(this.middleName); sb.append("Last Name : "); sb.append(this.lastName); return sb.toString(); } } public class TransientExample{ public static void main(String args[]) throws Exception { NameStore nameStore = new NameStore("Steve", "Middle","Jobs"); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("nameStore")); // writing to object o.writeObject(nameStore); o.close(); // reading from object ObjectInputStream in = new ObjectInputStream(new FileInputStream("nameStore")); NameStore nameStore1 = (NameStore)in.readObject(); System.out.println(nameStore1); } }
출력은 다음과 같습니다.
First Name : Steve Middle Name : null Last Name : Jobs
중간 이름 transient
으로 선언되어 영구 저장소에 저장되지 않습니다.
Community Wiki
직렬화하지 않으려는 변수를 정의할 수 있습니다.
객체에는 직렬화/지속하고 싶지 않은 정보(아마도 상위 팩토리 객체에 대한 참조)가 있거나 직렬화하는 것이 합리적이지 않을 수 있습니다. 이들을 '일시적'으로 표시하면 직렬화 메커니즘이 이러한 필드를 무시합니다.
Brian Agnew
Java에 임시 필드가 필요한 이유는 무엇입니까?
transient
키워드는 직렬화 프로세스에 대한 일부 제어를 제공하고 이 프로세스에서 일부 개체 속성을 제외할 수 있습니다. 직렬화 프로세스는 Java 객체를 유지하는 데 사용되며, 대부분이 객체가 전송되거나 비활성화되는 동안 상태가 보존될 수 있습니다. 때로는 객체의 특정 속성을 직렬화하지 않는 것이 합리적입니다.
어떤 필드를 일시적으로 표시해야 합니까?
transient
키워드와 일시적인 필드의 목적을 알았으므로 일시적으로 표시할 필드를 아는 것이 중요합니다. 정적 필드도 직렬화되지 않으므로 해당 키워드도 트릭을 수행합니다. 그러나 이것은 클래스 디자인을 망칠 수 있습니다. 이것은 transient
키워드가 구출되는 곳입니다. 다른 값에서 파생될 수 있는 필드가 직렬화되는 것을 허용하지 않으므로 임시로 표시합니다. principal
, rate
& time
)에서 값을 계산할 수 있는 interest
라는 필드가 있는 경우 직렬화할 필요가 없습니다.
또 다른 좋은 예는 기사 단어 수입니다. 전체 기사를 저장하는 경우 기사가 "역직렬화"될 때 계산될 수 있기 때문에 단어 수를 저장할 필요가 없습니다. 또는 로거에 대해 생각해 보십시오. Logger
인스턴스는 직렬화할 필요가 거의 없으므로 일시적으로 만들 수 있습니다.
Shreyos Adikari
transient
변수는 클래스가 직렬화될 때 포함되지 않는 변수입니다.
이것이 유용할 수 있는 한 가지 예는 특정 개체 인스턴스의 컨텍스트에서만 의미가 있고 개체를 직렬화 및 역직렬화하면 유효하지 않게 되는 변수입니다. 이 경우에는 필요할 때 유용한 데이터로 다시 초기화할 수 있도록 null
Adrian Grigore
기본 Java 이외의 직렬화 시스템에서도 이 수정자를 사용할 수 있습니다. 예를 들어, 최대 절전 모드는 @Transient 또는 일시적 수정자로 표시된 필드를 유지하지 않습니다. 테라코타도 이 수정자를 존중합니다.
수정자의 비유적인 의미는 "이 필드는 메모리 내 전용입니다. 어떤 식으로든 이 특정 VM 외부로 유지하거나 이동하지 마십시오. 이식할 수 없습니다."입니다. 즉, 다른 VM 메모리 공간의 값에 의존할 수 없습니다. volatile 과 마찬가지로 특정 메모리 및 스레드 의미 체계에 의존할 수 없습니다.
DragonFax
transient
는 클래스 필드를 직렬화할 필요가 없음을 나타내는 데 사용됩니다. 아마도 가장 좋은 예는 Thread
필드일 것입니다. 상태가 매우 '흐름에 따라 Thread
지기' 때문에 일반적으로 Thread 를 직렬화할 이유가 없습니다.
Andrei Ciobanu
모든 변수가 직렬화 가능한 것은 아니기 때문에
Silfverstrom
이 질문에 답하기 전에 직렬화에 대해 설명해야 합니다. 과학 컴퓨터에서 직렬화의 의미를 이해하면 이 키워드를 쉽게 이해할 수 있기 때문입니다.
객체가 네트워크를 통해 전송/물리적 매체(파일,...)에 저장될 때 객체는 "직렬화"되어야 합니다. 직렬화는 바이트 상태 개체 시리즈를 변환합니다. 이 바이트는 네트워크로 전송/저장되고 이 바이트에서 개체가 다시 생성됩니다.
예시:
public class Foo implements Serializable { private String attr1; private String attr2; ... }
이제 이 클래스에 전송하거나 저장하고 싶지 않은 필드가 있는 경우 transient
키워드를 사용할 수 있습니다.
private transient attr2;
이렇게 하면 클래스가 직렬화될 때 필드 형식이 포함되지 않습니다.
BERGUIGA Mohamed Amine
직렬화와 관련된 일부 민감한 데이터를 공유하고 싶지 않을 때 필요합니다.
setzamora
Google에 따르면 일시적인 의미 == 짧은 시간 동안만 지속됩니다. 영구적인.
이제 자바에서 일시적인 것을 만들고 싶다면 transient 키워드를 사용하십시오.
Q: 과도기를 어디에서 사용합니까?
A: 일반적으로 Java에서는 변수에서 데이터를 수집하고 해당 변수를 파일에 쓰는 방식으로 데이터를 파일에 저장할 수 있습니다. 이 프로세스를 직렬화라고 합니다. 이제 변수 데이터가 파일에 기록되는 것을 방지하려면 해당 변수를 일시적으로 만듭니다.
transient int result=10;
참고: 일시적인 변수는 로컬일 수 없습니다.
Mateen
일시적인 키워드에 대한 단순화된 예제 코드입니다.
import java.io.*; class NameStore implements Serializable { private String firstName, lastName; private transient String fullName; public NameStore (String fName, String lName){ this.firstName = fName; this.lastName = lName; buildFullName(); } private void buildFullName() { // assume building fullName is compuational/memory intensive! this.fullName = this.firstName + " " + this.lastName; } public String toString(){ return "First Name : " + this.firstName + "\nLast Name : " + this.lastName + "\nFull Name : " + this.fullName; } private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException { inputStream.defaultReadObject(); buildFullName(); } } public class TransientExample{ public static void main(String args[]) throws Exception { ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("ns")); o.writeObject(new NameStore("Steve", "Jobs")); o.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream("ns")); NameStore ns = (NameStore)in.readObject(); System.out.println(ns); } }
Mohammed H
간단히 말해서, 일시적인 자바 키워드는 비일시적인 필드 카운터 부분으로 직렬화에서 필드를 보호합니다.
이 코드 조각에서 추상 클래스 BaseJob은 Serializable 인터페이스를 구현하고 BaseJob에서 확장하지만 원격 및 로컬 데이터 소스를 직렬화할 필요는 없습니다. organizationName 및 isSynced 필드만 직렬화합니다.
public abstract class BaseJob implements Serializable{ public void ShouldRetryRun(){} } public class SyncOrganizationJob extends BaseJob { public String organizationName; public Boolean isSynced @Inject transient RemoteDataSource remoteDataSource; @Inject transient LocalDaoSource localDataSource; public SyncOrganizationJob(String organizationName) { super(new Params(BACKGROUND).groupBy(GROUP).requireNetwork().persist()); this.organizationName = organizationName; this.isSynced=isSynced; } }
nyulan
일시적인 수정자로 선언된 필드는 직렬화된 프로세스에 참여하지 않습니다. 객체가 직렬화(어떤 상태로 저장)될 때, 임시 필드의 값은 직렬 표현에서 무시되고 임시 필드 이외의 필드는 직렬화 프로세스에 참여합니다. 이것이 transient 키워드의 주요 목적입니다.
Vishal Sheth
모든 변수가 직렬화 가능한 것은 아니기 때문입니다.
- 직렬화 및 역직렬화는 대칭 프로세스입니다. 그렇지 않으면 결과가 결정될 것으로 기대할 수 없습니다. 대부분의 경우 결정되지 않은 값은 의미가 없습니다.
- 직렬화와 역직렬화는 멱등적이며 원하는 만큼 직렬화를 수행할 수 있으며 결과는 동일합니다.
따라서 Object가 메모리에는 존재할 수 있지만 디스크에는 존재할 수 없는 경우 역직렬화 시 시스템이 메모리 맵을 복원할 수 없기 때문에 Object를 직렬화할 수 없습니다. Stream
개체를 직렬화할 수 없습니다.
Connection
개체는 상태가 원격 사이트에 종속되기 때문에 직렬화할 수 없습니다.
Yu Jiaao
출처 : http:www.stackoverflow.com/questions/910374/why-does-java-have-transient-fields
'etc. > StackOverFlow' 카테고리의 다른 글
'git reset'을 취소하는 방법은 무엇입니까? (0) | 2022.02.15 |
---|---|
Bash 셸 스크립트에서 입력 인수의 존재 확인 (0) | 2022.02.15 |
"git commit" 대신 수행된 "git commit --amend"를 실행 취소하는 방법 (0) | 2022.02.15 |
숨김에 대한 Git diff (0) | 2022.02.15 |
가계도 소프트웨어의 주기 (0) | 2022.02.15 |