私はここに厄介な問題に直面しています、私は階層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で発生しました。
ありがとうございました。
一般に、抽象クラスをインスタンス化することはできませんし、インタフェースをインスタンス化することもできません。あなたはabstactクラスを拡張する必要があります。 – baudo2048
それはポイントです、私は抽象クラスをインスタンス化していない、私はパーセルが基本クラスを呼び出す理由を理解できません、それは子供ではありません。 – Leonardo
提供されたスタックトレースは、Gsonが抽象クラスのインスタンス化に問題があることを示しているようです。とにかく私の問題を解決するわけではありませんが、これはGithubでも同様です。https://github.com/johncarl81/parceler/issues/237 –