Java에 임시 필드가 있는 이유는 무엇입니까?
Java에 임시 필드가 있는 이유는 무엇입니까?
그transient
Java 키워드는 필드가 시리얼라이제이션(파일처럼 저장됨) 프로세스의 일부가 아님을 나타내기 위해 사용됩니다.
Java Language Specification, 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
메서드는 오버라이드되므로 썸네일이 생성되고generateThumbnail
방법.
자세한 내용은 기사 "Discover the Java Serialization API" (원래는 Sun Developer Network에서 사용 가능)에 대한 섹션이 있습니다.이 섹션에는 다음과 같은 시나리오가 있습니다.transient
키워드는 특정 필드의 시리얼화를 방지하기 위해 사용합니다.
를 이해하기 전에transient
키워드는 시리얼화의 개념을 이해해야 합니다.독자가 시리얼화에 대해 알고 있는 경우는, 첫 번째 포인트는 생략해 주세요.
시리얼라이제이션이란?
직렬화는 개체의 상태를 영속적으로 만드는 프로세스입니다.즉, 오브젝트 상태가 지속(예를 들어 파일에 바이트 저장) 또는 전송(예를 들어 네트워크를 통한 바이트 전송)에 사용되는 바이트 스트림으로 변환됩니다.마찬가지로 역직렬화를 사용하여 바이트에서 오브젝트 상태를 되돌릴 수 있습니다.이것은 Java 프로그래밍에서 중요한 개념 중 하나입니다. 왜냐하면 직렬화는 네트워킹 프로그래밍에서 주로 사용되기 때문입니다.네트워크를 통해 전송해야 하는 오브젝트는 바이트로 변환해야 합니다.그러기 위해서는 모든 클래스 또는 인터페이스에서 인터페이스를 구현해야 합니다.이것은 메서드가 없는 마커 인터페이스입니다.
자, 이제 무엇이냐?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
영구 스토리지에 저장되지 않습니다.
직렬화하지 않을 변수를 정의할 수 있습니다.
오브젝트에는 시리얼화/영속화하지 않는 정보(부모 팩토리 오브젝트에 대한 참조 등)가 있는 경우가 있습니다.또는 시리얼화 하는 것이 적절하지 않을 수 있습니다.이러한 필드를 '과도적'으로 표시하면 직렬화 메커니즘은 이러한 필드를 무시합니다.
Java에서 임시 필드가 필요한 이유는 무엇입니까?
그transient
키워드를 지정하면 시리얼라이제이션프로세스를 제어할 수 있어 이 프로세스에서 오브젝트 속성을 제외할 수 있습니다.시리얼라이제이션프로세스는 Java 오브젝트를 유지하기 위해 사용됩니다.대부분 Java 오브젝트가 전송되거나 비활성화되어도 상태를 유지할 수 있습니다.개체의 특정 속성을 직렬화하지 않는 것이 적절할 수 있습니다.
임시로 표시할 필드를 선택하십시오.
이제 그 목적을 알게 되었으니transient
키워드 및 과도 필드, 과도 필드를 알아두는 것이 중요합니다.스태틱 필드도 시리얼화되지 않기 때문에 대응하는 키워드도 유효합니다.하지만 이것은 당신의 수업 디자인을 망칠 수 있습니다; 여기가 바로 그 장소입니다.transient
키워드는 구조에 사용됩니다.값이 다른 값에서 파생될 수 있는 필드를 직렬화하지 않도록 하기 위해 임시로 표시합니다.라고 하는 필드가 있는 경우interest
다른 필드에서 값을 계산할 수 있습니다(principal
,rate
&time
시리얼화할 필요가 없습니다.
또 다른 좋은 예는 기사 단어 수입니다.기사 전체를 저장할 경우 기사 수가 "비직렬화"될 때 계산될 수 있기 때문에 단어 수를 저장할 필요가 없습니다.벌목꾼에 대해 생각해 봅시다.Logger
인스턴스를 거의 시리얼화할 필요가 없기 때문에 일시적인 인스턴스가 될 수 있습니다.
A transient
variable은 클래스를 시리얼화할 때 포함되지 않는 변수입니다.
예를 들어 특정 오브젝트인스턴스의 컨텍스트에서만 의미가 있고 오브젝트의 시리얼화 및 시리얼화를 해제하면 무효가 되는 변수가 있습니다.이 경우, 이러한 변수들이 다음과 같이 되는 것이 유용합니다.null
대신 필요한 경우 유용한 데이터로 다시 초기화할 수 있습니다.
네이티브 Java 이외의 시리얼라이제이션시스템에서도 이 수식어를 사용할 수 있습니다.예를 들어 휴지 상태에서는 @Transient 또는 임시 수식자로 표시된 필드는 유지되지 않습니다.테라코타 또한 이 수식어를 존중한다.
이 수식어의 비유적인 의미는 "이 필드는 메모리 내에서만 사용할 수 있습니다.어떤 식으로든 이 특정 VM 밖으로 이 필드를 계속 이동하거나 하지 마십시오.포터블이 아닙니다.즉, 다른 VM 메모리 공간에서의 가치에는 의존할 수 없습니다.휘발성과 마찬가지로 특정 메모리 및 스레드 의미에 의존할 수 없습니다.
transient
클래스 필드를 시리얼화할 필요가 없음을 나타내기 위해 사용합니다.아마도 가장 좋은 예는Thread
필드입니다. 일반적으로는 이 파일을 연속화할 이유가 없습니다.Thread
그 상태는 매우 '흐름 고유'하기 때문입니다.
이 질문에 답하기 전에, 저는 직렬화에 대해 설명할 필요가 있습니다. 왜냐하면 과학 컴퓨터에서의 직렬화의 의미를 이해한다면 이 키워드를 쉽게 이해할 수 있기 때문입니다.
개체를 네트워크를 통해 전송하거나 물리적 미디어(파일,...)에 저장하는 경우 개체를 "직렬화"해야 합니다.직렬화는 바이트 상태 개체 시리즈를 변환합니다.이러한 바이트는 네트워크 또는 저장된 바이트로 전송되고 개체는 이러한 바이트에서 다시 생성됩니다.
예제:
public class Foo implements Serializable
{
private String attr1;
private String attr2;
...
}
이 클래스에 전송하거나 저장하지 않을 필드가 있는 경우transient
키워드
private transient attr2;
이렇게 하면 클래스를 직렬화할 때 필드 양식이 포함되지 않습니다.
모든 변수가 직렬화할 수 있는 특성은 아니기 때문입니다.
시리얼화에 수반하는 기밀 데이터를 공유하고 싶지 않은 경우에 필요합니다.
구글 과도현상(google transient)에 따르면 ==는 단기간 동안만 지속되며 영구적이지 않습니다.
Java에서 과도 키워드를 사용하는 경우 transient 키워드를 사용합니다.
Q: 과도 사용처는 어디입니까?
A: 일반적으로 Java에서는 변수를 취득하여 파일에 쓰는 방법으로 데이터를 저장할 수 있습니다.이 프로세스를 Serialization이라고 합니다.변수 데이터가 파일에 기록되지 않도록 하려면 해당 변수를 임시로 설정합니다.
transient int result=10;
참고: 과도 변수는 로컬일 수 없습니다.
transient-keyword의 간단한 예시 코드.
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);
}
}
즉, transient java 키워드 protect 필드는 에서 비과도 필드 카운터 부분으로 Serialize되었습니다.
이 코드에서는 추상 클래스 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;
}
}
일시적 수식자로 선언된 필드는 직렬화된 프로세스에 참여하지 않습니다.오브젝트가 시리얼화(어느 상태로 저장)되면 해당 과도 필드의 값은 시리얼 표현에서 무시되고 과도 필드 이외의 필드는 시리얼화 프로세스에 참여합니다.이것이 transient 키워드의 주된 목적입니다.
모든 변수가 직렬화할 수 있는 특성은 아니기 때문입니다.
- 시리얼라이제이션과 디시리얼라이제이션은 대칭 프로세스입니다.결과를 예측할 수 없다면 대부분의 경우 미결정 값은 의미가 없습니다.
- 시리얼라이제이션과 디시리얼라이제이션은 동일하며 원하는 횟수만큼 시리얼라이제이션이 가능하며 결과는 동일합니다.
따라서 오브젝트가 메모리에는 존재할 수 있지만 디스크에는 존재할 수 없는 경우에는 시리얼화 해제 시 머신이 메모리 맵을 복원할 수 없기 때문에 오브젝트를 시리얼화할 수 없습니다.예를 들어 serialize는 할 수 없습니다.Stream
물건.
를 시리얼화할 수 없습니다.Connection
오브젝트. 리모트사이트에 따라 상태가 달라지기 때문입니다.
언급URL : https://stackoverflow.com/questions/910374/why-does-java-have-transient-fields
'programing' 카테고리의 다른 글
sizeof(x++)가 x가 증가하지 않는 이유는 무엇입니까? (0) | 2022.08.16 |
---|---|
JPA에 @Transient 주석이 있는 이유는 무엇입니까? (0) | 2022.08.16 |
vue composition api는 이름 경합을 어떻게 해결합니까? (0) | 2022.08.16 |
GSON - 날짜 형식 (0) | 2022.08.16 |
유닛 테스트 작성 방법 (0) | 2022.08.16 |