Generic Class with Constraint access issue

前端 未结 2 920
耶瑟儿~
耶瑟儿~ 2021-02-14 22:51

This a general JAVA question. In android, there is an interface Parcelable:

This is an example inside the official documentation:

 public class MyParcela         


        
相关标签:
2条回答
  • 2021-02-14 23:25

    Instead of <T extends Parcelable> you need <T extends ShushContainer<T> & Parcelable> this way you specify that T is ShushContainer so you can access is methods and variables.

    public class ShushContainer<T extends ShushContainer<T> & Parcelable> 
    implements Parcelable
    

    Here is the example using Serializable

    class Sample<T extends Sample<T> & Serializable> implements Serializable {
    
      public static int CONST = 0;
    
       public void foo()
       {
         T.CONST = 5;
       }
    }
    

    Update

    If I understand correctly threre is another class which implements Parcelable which has CREATOR You are trying dynamic polymorphism for Static variables which is not possible.

    Sample example to show how it fails

    public class Base {
        public static int count = 10;
    }
    
    public class Child extends Base {
        public static int count = 20;
    }
    
    
    class Sample<T extends Base> {
        T t = null;
        public void printCount() {
            System.out.println(T.count);
        }
        public Sample(T t) {
            this.t = t;
        }
    
        public static void main(String[] args) {
            Sample<Child> sample = new Sample<Child>(new Child());
            Sample<Base> sample1 = new Sample<Base>(new Base());
            sample.printCount();//Child value printed as 10
            sample1.printCount();//Same for parent value printed as  10
        }
    
    }
    

    This program fails because static fields are bound to Class rather than instance so there are two separate count one for Base and one for Child if you access value of Base then it will always be 10.

    You can use reflection to check whether CREATOR field is present and access it.Which will not be possible without object or class object.

    Or You can do something like below using TypeToken

    class Sample<T extends Serializable> implements Serializable {
    
        public int abc = 0;
        public void foo() {
        }
        public static void main(String[] args) throws SecurityException, NoSuchFieldException {
            TypeToken<Sample<Integer>> token = new TypeToken<Sample<Integer>>() {
            };
            Class<?> t = token.getRawType();
            Field field = t.getDeclaredField("abc");
            field.setAccessible(true);
            System.out.println(field.getName());
    
        }
    }
    
    0 讨论(0)
  • 2021-02-14 23:26

    This doesn't answer your question as to how to access the static CREATOR property, however you do not need to access this property implement Parcelable. See below for example:

    public class TestModel<T extends Parcelable> implements Parcelable {
    
    private List<T> items;
    private String someField;
    
    public List<T> items() {
        return items;
    }
    
    public void setItems(List<T> newValue) {
        items = newValue;
    }
    
    public String someField() {
        return someField;
    }
    
    public void setSomeField(String newValue) {
        someField = newValue;
    }
    
    //region: Parcelable implementation
    
    public TestModel(Parcel in) {
        someField = in.readString();
    
        int size = in.readInt();
        if (size == 0) {
            items = null;
        }
    
        else {
    
            Class<?> type = (Class<?>) in.readSerializable();
    
            items = new ArrayList<>(size);
            in.readList(items, type.getClassLoader());
        }
    }
    
    @Override
    public int describeContents() {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(someField);
    
        if (items == null || items.size() == 0)
            dest.writeInt(0);
    
        else {
            dest.writeInt(items.size());
    
            final Class<?> objectsType = items.get(0).getClass();
            dest.writeSerializable(objectsType);
    
            dest.writeList(items);
        }
    
        dest.writeInt(items.size());
        for(int i=0;i<items.size();i++)
            items.get(i).writeToParcel(dest, flags);
    }
    
    public static final Parcelable.Creator<TestModel> CREATOR = new Parcelable.Creator<TestModel>() {
        public TestModel createFromParcel(Parcel in) {
            return new TestModel(in);
        }
    
        public TestModel[] newArray(int size) {
            return new TestModel[size];
        }
    };
    
    //endregion
    }
    
    0 讨论(0)
提交回复
热议问题