java - 具有约束访问问题的通用类

标签 java android

这是一个一般的 JAVA 问题。在android中,有一个接口(interface) Parcelable :

这是 official documentation 中的一个示例:

 public class MyParcelable implements Parcelable {
     private int mData;

     public int describeContents() {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mData);
     }

     public static final Parcelable.Creator<MyParcelable> CREATOR
             = new Parcelable.Creator<MyParcelable>() {
         public MyParcelable createFromParcel(Parcel in) {
             return new MyParcelable(in);
         }

         public MyParcelable[] newArray(int size) {
             return new MyParcelable[size];
         }
     };

     private MyParcelable(Parcel in) {
         mData = in.readInt();
     }
 }

我们需要实现这两个功能 describeContents()writeToParcel .

(问题) 除了它们,我们还需要实现 Parcelable.Creator<T>接口(interface)作为称为 CREATOR 的静态字段。

实际上一切都是直截了当的。现在我想创建一个具有 Parcelable 类类型的通用类:

public class ShushContainer<T extends Parcelable> implements Parcelable

我能够实现 Parcelable。我可以调用 TwriteToParcel功能。但是,我无法访问静态 CREATOR 字段。

public class ShushContainer<T extends Parcelable> implements Parcelable {
    Vector<T> items;
    String someField;

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(someField);
        dest.writeInt(items.size());
        for(int i=0;i<items.size();i++)
            items.get(i).writeToParcel(dest, flags);
    }

    public ShushContainer(Parcel in) {
        someField = in.readString();
        int size = in.readInt();
        for(int i=0;i<size;i++)
            //this does not work
            items.add(T.CREATOR.createFromParcel(in));
    }

    public static final Parcelable.Creator<ShushContainer> CREATOR = new Parcelable.Creator<ShushContainer>() {
        public ShushContainer createFromParcel(Parcel in) {
            return new ShushContainer(in);
        }

        public ShushContainer[] newArray(int size) {
            return new ShushContainer[size];
        }
    };
}

最佳答案

而不是 <T extends Parcelable>你需要<T extends ShushContainer<T> & Parcelable>这样你指定 TShushContainer这样您就可以访问方法和变量。

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

这是使用 Serializable 的示例

class Sample<T extends Sample<T> & Serializable> implements Serializable {

  public static int CONST = 0;

   public void foo()
   {
     T.CONST = 5;
   }
}

更新

如果我理解正确的话,还有另一个实现了 Parcelable 的类其中有 CREATOR 您正在尝试静态变量的动态多态性,这是不可能的。

展示它如何失败的示例

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
    }

}

这个程序失败是因为静态字段绑定(bind)到类而不是实例所以有两个独立的count一个用于 Base和一个 Child如果您访问 Base 的值那么它将永远是 10。

您可以使用反射来检查是否CREATOR字段存在并访问它。如果没有对象或类对象,这是不可能的。

或者您可以使用 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());

    }
}

关于java - 具有约束访问问题的通用类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12601489/

相关文章:

java - 使用旧数组的内容创建新数组,同时保持旧数组静态

java - 如何在 firebase 中将旧数据与新数据相加

java - 如何正确生成 grpc java auth 示例所需的 .pem 文件?

java - 如何列出资源目录中的所有文件

android - Flutter 应用程序无法在 iOS 平台上运行

java - 如何显示列表的内容?

android - 调整 Windroy 窗口的大小

java - 编辑字符串中的结果等于 false

java - 在 EditText (Android) 中过滤多个空格

java - 在 Android 上将 Admob SDK 与 Mopub 集成