无法实例化抽象 class 'base.CreditCard'
Can't instantiate abstract class 'base.CreditCard'
我在这里遇到了一个棘手的问题,我试图让层次结构可打包 classes 但我遇到了这个奇怪的错误:
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.construct()(ConstructorConstructor.java:104)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read()(ReflectiveTypeAdapterFactory.java:186)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.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.access0()(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()));
}
}
}
还有一个child class:
@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,但我似乎无法弄清楚发生了什么。
Parceler 1.1.5 版本出现此问题。
谢谢。
我相信您 运行 遇到了这个问题:
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.
所以您应该能够使用自定义序列化来解决这个问题。
实际上我忘记在我的序列化程序中添加 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);
抱歉打扰了,希望对别人有帮助!
我在这里遇到了一个棘手的问题,我试图让层次结构可打包 classes 但我遇到了这个奇怪的错误:
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.construct()(ConstructorConstructor.java:104)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read()(ReflectiveTypeAdapterFactory.java:186)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.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.access0()(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()));
}
}
}
还有一个child class:
@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,但我似乎无法弄清楚发生了什么。
Parceler 1.1.5 版本出现此问题。
谢谢。
我相信您 运行 遇到了这个问题:
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.
所以您应该能够使用自定义序列化来解决这个问题。
实际上我忘记在我的序列化程序中添加 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);
抱歉打扰了,希望对别人有帮助!