2016-09-15 12 views
1

私はここに厄介な問題に直面しています、私は階層parcelableのクラスを持ってしようとしているが、私はこの奇妙なエラーになっています:は、抽象クラスをインスタンス化することはできません「base.CreditCard」

java.lang.InstantiationException: Can't instantiate abstract class br.com.dinda.models.credit_cards.base.CreditCard 
    at java.lang.reflect.Constructor.newInstance()(Constructor.java:-2) 
    at com.google.gson.internal.ConstructorConstructor$3.construct()(ConstructorConstructor.java:104) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read()(ReflectiveTypeAdapterFactory.java:186) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read()(ReflectiveTypeAdapterFactory.java:103) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read()(ReflectiveTypeAdapterFactory.java:196) 
    at com.google.gson.Gson.fromJson()(Gson.java:810) 
    at com.google.gson.Gson.fromJson()(Gson.java:775) 
    at com.google.gson.Gson.fromJson()(Gson.java:724) 
    at com.google.gson.Gson.fromJson()(Gson.java:696) 
    at com.newrelic.agent.android.instrumentation.GsonInstrumentation.fromJson()(GsonInstrumentation.java:90) 
    at br.com.dinda.models.CheckoutData.fromJson()(CheckoutData.java:38) 
    at br.com.dinda.repositories.CheckoutRepository.getPersistedCheckout()(CheckoutRepository.java:46) 
    at br.com.dinda.repositories.CheckoutRepository.getCheckout()(CheckoutRepository.java:28) 
    at br.com.dinda.presenters.CheckoutStep2Presenter.onCreate()(CheckoutStep2Presenter.java:43) 
    at br.com.dinda.views.fragments.CheckoutStep2Fragment.onCreateView()(CheckoutStep2Fragment.java:183) 
    at android.support.v4.app.Fragment.performCreateView()(Fragment.java:1789) 
    at android.support.v4.app.FragmentManagerImpl.moveToState()(FragmentManager.java:955) 
    at android.support.v4.app.FragmentManagerImpl.moveToState()(FragmentManager.java:1138) 
    at android.support.v4.app.FragmentManagerImpl.moveToState()(FragmentManager.java:1120) 
    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated()(FragmentManager.java:1929) 
    at android.support.v4.app.FragmentActivity.onStart()(FragmentActivity.java:547) 
    at android.support.v7.app.AppCompatActivity.onStart()(AppCompatActivity.java:-1) 
    at br.com.dinda.views.activities.BaseActivity.onStart()(BaseActivity.java:49) 
    at android.app.Instrumentation.callActivityOnStart()(Instrumentation.java:1238) 
    at android.app.Activity.performStart()(Activity.java:6288) 
    at android.app.ActivityThread.performLaunchActivity()(ActivityThread.java:2397) 
    at android.app.ActivityThread.handleLaunchActivity()(ActivityThread.java:2494) 
    at android.app.ActivityThread.access$900()(ActivityThread.java:157) 
    at android.app.ActivityThread$H.handleMessage()(ActivityThread.java:1356) 
    at android.os.Handler.dispatchMessage()(Handler.java:102) 
    at android.os.Looper.loop()(Looper.java:148) 
    at android.app.ActivityThread.main()(ActivityThread.java:5530) 
    at java.lang.reflect.Method.invoke()(Method.java:-2) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()(ZygoteInit.java:733) 
    at com.android.internal.os.ZygoteInit.main()(ZygoteInit.java:623) 

私のコードを次のとおりです。

@Parcel(converter = CreditCard.CreditCardConverter.class) 
public abstract class CreditCard { 

    public static final String CREDIT_CARD_MASK = "**** **** **** ####"; 
    public static ImmutableList<CreditCard> CREDIT_CARD_OPERATORS; 

    static { 
     CREDIT_CARD_OPERATORS = ImmutableList.of(
       new EloCreditCard(), 
       new VisaCreditCard(), 
       new MastercardCreditCard(), 
       new HipercardCreditCard() 
     ); 
    } 

    @SerializedName("credit_card_id") 
    Integer id; 

    @SerializedName("credit_card_name") 
    String name; 

    @SerializedName("credit_card_number") 
    String number; 

    @SerializedName("credit_card_month") 
    Integer month; 

    @SerializedName("credit_card_year") 
    Integer year; 

    @SerializedName("credit_card_operator") 
    String operator; 

    String securityCode; 

    boolean saveCreditCard; 

    /** 
    * Funcao para retornar o nome da operadora do cartao 
    * eg. visa ou mastercard 
    * @return nome da operadora 
    */ 
    @NonNull 
    public abstract String getCreditCardOperatorName(); 

    /** 
    * Funcao que retorna o regex para verificar a validade da operadora do cartao (nums sao validos para a bandeira especificada) 
    * eg. visa = Pattern.compile("^4[0-9]{15}$"), 
    * @return @Pattern para a operadora especificada 
    */ 
    public abstract Pattern creditCardRegex(); 

    /** 
    * Funcao que retorna o Regex parcial para identificar a operadora do cartao 
    * * eg. visa = Pattern.compile("^4[0-9]*$") 
    * @return @Pattern para a verificacao parcial da operadora do cartao 
    */ 
    public abstract Pattern partialCreditCardRegex(); 

    /** 
    * Funcao que retorna o logo da bandeira da operadaora do cartao quando o msm esta selecionado 
    * @return Drawable do logo 
    */ 
    @DrawableRes 
    public abstract int operatorLogoRes(); 

    /** 
    * Funcao que retorna o logo da bandeira da operadaora do cartao quando o msm <b>nao</b> esta selecionado 
    * @return Drawable do logo desmarcado (cinza) 
    */ 
    @DrawableRes 
    public abstract int operatorLogoDisabledRes(); 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (!(o instanceof CreditCard)) return false; 

     CreditCard card = (CreditCard) o; 

     return getCreditCardOperatorName().equals(card.getCreditCardOperatorName()); 

    } 

    @Override 
    public int hashCode() { 
     return getCreditCardOperatorName().hashCode(); 
    } 

    public static class CreditCardConverter implements ParcelConverter<CreditCard> { 

     @Override 
     public void toParcel(CreditCard input, android.os.Parcel parcel) { 
      parcel.writeParcelable(Parcels.wrap(input), 0); 
     } 

     @Override 
     public CreditCard fromParcel(android.os.Parcel parcel) { 
      return Parcels.unwrap(parcel.readParcelable(CreditCard.class.getClassLoader())); 
     } 
    } 
} 

と子クラス:

@Parcel 
public class HipercardCreditCard extends CreditCard { 

    @Override 
    public String getCreditCardOperatorName() { 
     return "hipercard"; 
    } 

    @Override 
    public Pattern creditCardRegex() { 
     return Pattern.compile("^606282[0-9]{10}$"); 
    } 

    @Override 
    public Pattern partialCreditCardRegex() { 
     return Pattern.compile("^(?:6|60|606|6062|60628|606282[0-9]{0,10})$"); 
    } 

    @Override 
    public int operatorLogoRes() { 
     return R.drawable.ic_credit_card_hipercard_on; 
    } 

    @Override 
    public int operatorLogoDisabledRes() { 
     return R.drawable.ic_credit_card_hipercard_off; 
    } 
} 

私は@Parcelとしてそれらに注釈を付けるの世話をしたが、私はFiに見えることはできません何が起こっているかを調べる。

この問題はParcelerのバージョン1.1.5で発生しました。

ありがとうございました。

+0

一般に、抽象クラスをインスタンス化することはできませんし、インタフェースをインスタンス化することもできません。あなたはabstactクラスを拡張する必要があります。 – baudo2048

+0

それはポイントです、私は抽象クラスをインスタンス化していない、私はパーセルが基本クラスを呼び出す理由を理解できません、それは子供ではありません。 – Leonardo

+0

提供されたスタックトレースは、Gsonが抽象クラスのインスタンス化に問題があることを示しているようです。とにかく私の問題を解決するわけではありませんが、これはGithubでも同様です。https://github.com/johncarl81/parceler/issues/237 –

答えて

1

実は、私は私のシリアライザCustomTypeAdapterに追加するのを忘れ、

if (json != null) { 
      Gson gson = new Gson(); 
      return gson.fromJson(json, CheckoutData.class); 

は次のようになります。

if (json != null) { 
      Gson gson = new GsonBuilder().registerTypeAdapter(CreditCard.class, new CreditCardTypeAdapter()).create(); 
      return gson.fromJson(json, CheckoutData.class); 

邪魔して申し訳ありませんが、それは他の誰かに役立ちます願っています!

0

私はあなたがこの問題に実行していると信じて:

Polymorphism

Note that Parceler does not unwrap inheritance hierarchies, so any polymorphic fields will be unwrapped as instances of the base class. This is because Parceler opts for performance rather than checking .getClass() for every piece of data.

@Parcel public class Example { 
    public Parent p; 
    @ParcelConstructor Example(Parent p) { this.p = p; } } 

@Parcel public class Parent {} @Parcel public class Child extends 
Parent {} Example example = new Example(new Child()); 
System.out.println("%b", example.p instanceof Child); // true example 
= Parcels.unwrap(Parcels.wrap(example)); System.out.println("%b", example.p instanceof Child); // false 

Refer to the Custom Serialization section for an example of working with polymorphic fields.

だから、あなたがこの問題を回避するには、カスタムのシリアル化を使用することができるはずです。

https://github.com/johncarl81/parceler#custom-serialization

関連する問題