2016-02-18 15 views
5

neden olur StackOverflowError neden olur:GSON: Bir java.nio.Path seri StackOverflowError bu Dizgeleştirme

import java.nio.file.Path; 
import java.nio.file.Paths; 

public class Tmp{ 
    private Path path=null; 
    public Tmp() { 
     path=Paths.get("c:\\temp\\"); 
    } 
} 

Bana bir böcek gibi görünüyor! Ya da yanlış bir şey yapıyorum? (dize yolunu dönüştüren bazı özel seri hale yazma bekliyoruz)

java.lang.StackOverflowError 
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:372) 

    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:381) 
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376) 
    ... 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:128) 

    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:75) 
    at com.google.gson.Gson.getAdapter(Gson.java:358) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.java:109) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.java:46) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:84) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:83) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:129) 
    ... 

Dizgeleştirme yöntemdir geçici çözüm var mı:

public static void saveTo(BatchLogging logging, Path path) throws IOException { 
    Gson gson=new GsonBuilder().setPrettyPrinting().create(); 
    // String json = gson.toJson(logging); 
    String json = gson.toJson(new Tmp()); 
    List<String> lines = Arrays.asList(json.split(System.lineSeparator())); 
    Files.write(path, lines, StandardCharsets.UTF_8); 
} 
+0

http://stackoverflow.com/q/36964995/1032167 daha fazla bilgi. Özel 'sınıf oluşturma PathConverter JsonDeserializer , JsonSerializer ' uygular ve '.registerTypeHierarchyAdapter (Path.class, yeni MyPathConverter())' – varren

cevap

3

bir ayıklayıcısında Paths.get("c:\\temp\\"); tarafından döndürülen nesne inceleyin. Makinemde, WindowsFileSystem içeren fs adlı bir alana sahiptir. Bu, bir WindowsFileSystemProvider içeren provider bir alana sahiptir ve provider, fs özgün fs alanı ile aynıiçeren bir alana sahiptir. Voila, döngüsel referans.

Gson, verdiğiniz nesnenin tüm geçici olmayan alanlarını denetlemek ve serileştirmek için yansımayı kullanır. Bu gibi döngüsel bir referans, onu StackOverflowError ile biten sonsuz yineleme içine gönderir. Bunu düzeltmek için, özel seri hale getirme uygulamak veya tüm nesne yerine Path belirli bir özelliği serileştirmeniz gerekir. Döngüde yer alan alanların herhangi birini veya tümünü transient olarak işaretlemek de işe yarardı, ancak bu kitaplığın koduna yazma erişimi gerektiriyordu.

+1

olarak kaydederim. Ancak aynı zamanda, bu sınıf Java 7'den beri temel bir Java sınıfıdır ve Gson tarafından doğru şekilde ele alınmalıdır. Her geliştiricinin bu sınıf için kendi serializer/deserializer uygulamasını gerçekleştirmesi gerekmiyor. Bu Gson'un temel bir özelliği olmalı. – lvr123

+1

@ lvr123 Bu, "Serializable" uygulamıyor ve amacı çoğunlukla veriyi depolamak için değil, ayrıştırmak, doğrulamak, kullanmak ve kullanmaktır. Ne Gson ne de herhangi bir diğer serileştirme kütüphanesi, özelleştirme için iyi bir nedene sahip değildir, çünkü serileştirme, 'Yol' ne için değildir. Harita ve Topluluğun birçok alt arayüzünde ana amaca yönelik veri depolama vardır ve Gson'un bunlar için özel bir kullanımı vardır. – Douglas

+2

Bu Nesne türünü serileştirmeyi ne öneriyorsunuz? – lvr123