Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 写入包裹时堆栈溢出错误_Java_Android_Parcelable - Fatal编程技术网

Java 写入包裹时堆栈溢出错误

Java 写入包裹时堆栈溢出错误,java,android,parcelable,Java,Android,Parcelable,我有两个类,假设它们看起来像这样: Movie.java public class Movie implements Parcelable { private int year; private List<Actor> actors; // Constructor, getters and setters, Parcelable implementation } 现在,当我试图将电影写入parcelable时,我得到StackOverflower错

我有两个类,假设它们看起来像这样:

Movie.java

public class Movie implements Parcelable { 
     private int year;
     private List<Actor> actors;

     // Constructor, getters and setters, Parcelable implementation
}
现在,当我试图将电影写入parcelable时,我得到StackOverflower错误:

java.lang.StackOverflowError
    at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1012)
    at java.util.concurrent.ConcurrentHashMap.putIfAbsent(ConcurrentHashMap.java:1535)
    at java.lang.ClassLoader.getClassLoadingLock(ClassLoader.java:463)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:404)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at android.os.Parcel.writeParcelable(Parcel.java)
    atcom.example.android.data.model.Actor.writeToParcel(Actor.java:58)
    at android.os.Parcel.writeTypedList(Parcel.java:1106)
    at com.example.android.data.model.Movie.writeToParcel(Movie.java:70)
我知道嵌套类有一个问题,因为当它试图将电影写到包中时,它试图写Actor,但在Actor中它又试图写电影

问题


如何避免嵌套类出现问题?

不要将
电影
存储在
演员
中。它们之间的双向关系正在产生错误


而且,
演员
应该存储
电影
,这一点也没有意义。现实生活中的演员可以在很多电影中出现,也可以没有,或者他们只演电视剧。

不要将
电影
存储在
演员
中。它们之间的双向关系正在产生错误

而且,
演员
应该存储
电影
,这一点也没有意义。现实生活中的演员可以在很多电影中出演,也可以不出演,或者他们只演电视剧。

实现一个新的角色。然后使用account for object identity序列化引用

Java序列化协议旨在处理对象之间的循环依赖关系。包裹不支持那些经过设计的——试图侵入这种支持将毫无意义地重复
ObjectInputStream
ObjectOutputStream
的创建者已经完成的工作。请注意,我不是建议实现Serializable(这很慢,因为它基于反射),而是建议实现Externalizable,这与Parcelable基本相同,只是它可以很好地实现序列化

ObjectOutputStream
本身既不可序列化也不可打包,但您可以将其定向到
ByteArrayOutputStream
并将生成的字节数组传递:

public static byte[] serialize(Externalizable object) {
    final ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    ObjectOutputStream objectStream = null;
    try {
        objectStream = new ObjectOutputStream(buffer);
        objectStream.writeObject(object);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        if (objectStream != null) {
            try { objectStream.close(); } catch (IOException ignored) {}
        }
    }

    return buffer.toByteArray();
}

public static <T extends Externalizable> T deserialize(byte[] bytes) {
    ObjectInputStream objectStream = null;
    try {
        objectStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        return (T) objectStream.readObject();
    } catch (IOException | ClassNotFoundException e) {
        throw new RuntimeException(e);
    } finally {
        if (objectStream != null) {
            try { objectStream.close(); } catch (IOException ignored) {}
        }
    }
}
电影:

class Movie implements Externalizable {
  private List<Actor> actors;

  private int year;

  public Movie(int year) {
    this.year = year;

    actors = new ArrayList<>();
  }

  public void addActors(Actor... actors) {
    Collections.addAll(this.actors, actors);
  }

  // required by Externalizable contract
  public Movie() {
  }

  @Override
  @SuppressWarnings("unchecked")
  public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
    year = input.read();
    actors = (List<Actor>) input.readObject();
  }

  @Override
  public void writeExternal(ObjectOutput output) throws IOException {
    output.write(year);
    output.writeObject(actors);
  }

  ...
}
类电影实现了外部化{
私人名单行动者;
私人国际年;
公共电影(国际年){
今年=年;
actors=newarraylist();
}
公共角色(角色…角色){
Collections.addAll(this.actors,actors);
}
//可外化合同要求
公共电影(){
}
@凌驾
@抑制警告(“未选中”)
public void readExternal(ObjectInput输入)引发IOException、ClassNotFoundException{
年份=输入。读取();
actors=(List)input.readObject();
}
@凌驾
public void writeExternal(ObjectOutput输出)引发IOException{
输出。写入(年);
output.writeObject(actors);
}
...
}
我刚刚在我的设备上进行了测试,并通过Intent成功地将交互引用的电影/演员传递到各个活动中。

改为实现一个。然后使用account for object identity序列化引用

Java序列化协议旨在处理对象之间的循环依赖关系。包裹不支持那些经过设计的——试图侵入这种支持将毫无意义地重复
ObjectInputStream
ObjectOutputStream
的创建者已经完成的工作。请注意,我不是建议实现Serializable(这很慢,因为它基于反射),而是建议实现Externalizable,这与Parcelable基本相同,只是它可以很好地实现序列化

ObjectOutputStream
本身既不可序列化也不可打包,但您可以将其定向到
ByteArrayOutputStream
并将生成的字节数组传递:

public static byte[] serialize(Externalizable object) {
    final ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    ObjectOutputStream objectStream = null;
    try {
        objectStream = new ObjectOutputStream(buffer);
        objectStream.writeObject(object);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        if (objectStream != null) {
            try { objectStream.close(); } catch (IOException ignored) {}
        }
    }

    return buffer.toByteArray();
}

public static <T extends Externalizable> T deserialize(byte[] bytes) {
    ObjectInputStream objectStream = null;
    try {
        objectStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        return (T) objectStream.readObject();
    } catch (IOException | ClassNotFoundException e) {
        throw new RuntimeException(e);
    } finally {
        if (objectStream != null) {
            try { objectStream.close(); } catch (IOException ignored) {}
        }
    }
}
电影:

class Movie implements Externalizable {
  private List<Actor> actors;

  private int year;

  public Movie(int year) {
    this.year = year;

    actors = new ArrayList<>();
  }

  public void addActors(Actor... actors) {
    Collections.addAll(this.actors, actors);
  }

  // required by Externalizable contract
  public Movie() {
  }

  @Override
  @SuppressWarnings("unchecked")
  public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
    year = input.read();
    actors = (List<Actor>) input.readObject();
  }

  @Override
  public void writeExternal(ObjectOutput output) throws IOException {
    output.write(year);
    output.writeObject(actors);
  }

  ...
}
类电影实现了外部化{
私人名单行动者;
私人国际年;
公共电影(国际年){
今年=年;
actors=newarraylist();
}
公共角色(角色…角色){
Collections.addAll(this.actors,actors);
}
//可外化合同要求
公共电影(){
}
@凌驾
@抑制警告(“未选中”)
public void readExternal(ObjectInput输入)引发IOException、ClassNotFoundException{
年份=输入。读取();
actors=(List)input.readObject();
}
@凌驾
public void writeExternal(ObjectOutput输出)引发IOException{
输出。写入(年);
output.writeObject(actors);
}
...
}

我刚刚在我的设备上进行了测试,能够通过Intent成功地在活动之间传递交叉引用电影/演员。

这将在将
电影
对象写入
包裹时创建一个无限循环,如果您确实需要从
演员
中引用
电影
,您可以尝试向
电影
类添加一个ID,并将此ID赋予
演员
,稍后您可以使用此ID跟踪相应的
电影
,尽管我不确定这是否仍然满足您的要求。无论如何,在OO语言中,使用循环引用是非常不受欢迎的。

这将在将
电影
对象写入
包裹时创建一个无限循环,如果您确实需要从
演员
中引用
电影
,您可以尝试向
电影
类添加一个ID,并将此ID赋予
演员
,稍后您可以使用此ID跟踪相应的
电影
,尽管我不确定这是否仍然满足您的要求。无论如何,在OO语言中,使用循环引用是非常不受欢迎的。

Post完整错误日志添加了两行,rest是相同的。这可能有助于检查此线程也可能重复Post完整错误日志添加了两行,rest是相同的。这可能有助于检查此线程也可能重复的来吧,这是假设。我知道这是在制造错误,我写过。如何处理这种模型结构?这是一种父子关系。最好的方法是只将子对象存储在父对象中,而不是相反