[java] Java에 왜 일시적인 필드가 있습니까?

Java에 왜 일시적인 필드가 있습니까?



답변

transientJava 의 키워드는 필드가 직렬화 ( 파일 과 같이 저장됨을 의미 함 ) 프로세스의 일부가 아니어야 함을 나타내는 데 사용됩니다 .

로부터 Java 언어 사양, 자바 SE 7 판 , 제 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.

추가 정보를 위해 , Java Serialization API 기사 (Sun Developer Network에서 원래 사용 가능) 의 비밀 발견transient 은 특정 필드의 직렬화를 막기 위해 키워드를 사용 하는 시나리오에 대해 설명하고 시나리오를 제시하는 섹션이 있습니다.


답변

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되므로 영구 저장소에 저장되지 않습니다.

출처


답변

직렬화하지 않을 변수를 정의 할 수 있습니다.

객체에는 직렬화 / 유지하지 않으려는 정보 (아마도 부모 팩토리 객체에 대한 참조)가 있거나 직렬화하는 것이 의미가 없습니다. 이를 ‘일시적’으로 표시하면 직렬화 메커니즘이이 필드를 무시합니다.


답변

나의 작은 기여 :

과도 필드 란 무엇입니까?
기본적으로 transient키워드로 수정 된 모든 필드 는 임시 필드입니다.

Java에서 임시 필드가 필요한 이유는 무엇입니까? 키워드는 당신에게 직렬화 프로세스 일부 제어를 제공하고이 과정에서 일부 개체 속성을 제외 할 수 있습니다. 직렬화 프로세스는 Java 오브젝트를 지속시키는 데 사용되며, 대부분 전송 또는 비활성 상태에서 해당 상태를 보존 할 수 있습니다. 때로는 객체의 특정 속성을 직렬화하지 않는 것이 좋습니다. 어떤 필드를 일시적으로 표시해야합니까?
이제 우리는
transient


transient키워드 및 과도 필드에서는 과도 필드를 표시 할 필드를 알아야합니다. 정적 필드도 직렬화되지 않으므로 해당 키워드도 트릭을 수행합니다. 그러나 이것은 클래스 디자인을 망칠 수 있습니다. 곳이다 transient키워드는 구조로되어 있습니다. 다른 값에서 파생 될 수있는 값을 가진 필드를 직렬화 할 수 없도록하기 위해 일시적으로 표시합니다. 당신이라는 필드가있는 경우 interest그 값이 다른 필드로부터 계산 (수 principal, rate&를 time) 직렬화 할 필요가 없습니다.

또 다른 좋은 예는 기사 단어 수입니다. 전체 기사를 저장하는 경우 기사가 “직렬화 해제”될 때 계산 될 수 있으므로 단어 수를 저장할 필요가 없습니다. 또는 로거에 대해 생각하십시오.Logger 인스턴스를 거의 직렬화 할 필요가 없으므로 일시적으로 만들 수 있습니다.


답변

transient변수 직렬화 될 수있는 변수이다.

이것이 유용 할 때 유용한 예 중 하나는 특정 객체 인스턴스의 컨텍스트에서만 의미가 있고 객체를 직렬화하고 역 직렬화하면 유효하지 않은 변수입니다. 이 경우 null필요할 때 유용한 데이터로 변수 를 다시 초기화 할 수 있도록 변수를 대신 사용하는 것이 좋습니다.


답변

transient클래스 필드를 직렬화 할 필요가 없음을 나타내는 데 사용됩니다. 아마도 가장 좋은 예는 Thread필드입니다. Thread상태가 ‘흐름에 따라’ 다르기 때문에 일반적으로를 직렬화 할 이유가 없습니다 .


답변

원시 Java 이외의 직렬화 시스템도이 수정자를 사용할 수 있습니다. 예를 들어, 최대 절전 모드는 @Transient 또는 transient 수정 자로 표시된 필드를 유지하지 않습니다 . 테라코타는이 수정자를 존중합니다.

수정 자의 비유적인 의미는 “이 필드는 메모리 내에서만 사용하기위한 것입니다. 어떤 방식 으로든이 특정 VM 외부로 유지하거나 옮기지 마십시오. 이식성이 없습니다”라고 생각합니다. 즉, 다른 VM 메모리 공간에서 그 값에 의존 할 수 없습니다. 휘발성 과 매우 흡사 하다는 것은 특정 메모리 및 스레드 의미에 의존 할 수 없음을 의미합니다.