2016-09-15 3 views
1

Ich bin hier ein unangenehmes Problem konfrontiert, ich versuche Hierarchie parcel Klassen zu haben, aber ich bin diesen bizarren Fehler bekommen:Kann nicht abstrakte Klasse instanziiert ‚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) 

Mein Code ist:

@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())); 
     } 
    } 
} 

Und ein Kind Klasse:

@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; 
    } 
} 

ich sie als @Parcel von annotieren kümmerten, aber ich kann nicht zu fi scheinen herauszufinden, was vor sich geht.

Dieses Problem ist bei Version 1.1.5 von Parceler aufgetreten.

Danke.

+0

Im Allgemeinen können Sie abstrakte Klasse nicht instanziieren sowie Schnittstelle nicht instanziieren. Sie müssen die Abstact-Klasse erweitern. – baudo2048

+0

Das ist der Punkt, ich bin nicht instanziieren die abstrakte Klasse, ich kann nicht verstehen, warum Parceler ruft die Basisklasse, nicht es Kinder. – Leonardo

+0

Der bereitgestellte Stack-Trace scheint auf Gson zu zeigen, dass die abstrakte Klasse nicht instanziiert werden konnte. Hier auf Github auch beantwortet: https://github.com/johncarl81/parceler/issues/237 –

Antwort

1

Eigentlich habe ich vergessen, in meinem Serializer die CustomTypeAdapter,

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

sein sollte hinzufügen:

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

Leider zu stören und hoffe, es hilft jemand anderes!

0

Ich glaube, Sie in dieses Problem laufen:

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.

So sollten Sie in der Lage sein, benutzerdefinierte Serialisierung zu verwenden, dies zu umgehen.

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

Verwandte Themen