简体   繁体   English

在Java中使用泛型传递类型参数

[英]Passing Type Parameters using Generics in Java

I am trying to make some more sense of Generics, and I have the following situation: 我正在尝试使泛型更有意义,并且我遇到以下情况:

// This is one of many Models I have that want to use like this, or similar
public class MyData{
    private String name;
    private String color;
    //... default constructor    

    //... setters and getters

}

and I have an abstract class: 我有一个抽象类:

public abstract class CacheAble<T>{

   // The idea is any T can be inserted
   public abstract <T> boolean insertCacheAble(T data);

   // The idea is any T can be deleted
   public abstract <T> boolean deleteCacheAble(T data);      

}

So what I would like to do is the following: 所以我想做的是以下几点:

 // Have my Operations for how i want to handle the methods on MyData
 public MyDataOps extends CacheAble<MyData>{

   //... Members

   public MyDataOps(){
       //.. initialize some other members
   }      

   @Override
   public <T> boolean insertCacheAble(T data){
       //... want to be able to Access MyData.name & MyData.color
       //... how can I do this?

      String name = data.getName();
      String color = data.getColor();

      //.. insert db values
   }

   @Override
   public <T> boolean deleteCacheAble(T data){

      String name = data.getName();
      String color = data.getColor();

      //... Perform db delete based on name or color
   }

 }

I am not very good with Java Generics as you can see so any pointing in the right direction would be very helpful! 如您所见,我对Java Generics不太满意,所以任何指向正确方向的建议都会非常有帮助! Should I implement this instead as a generic interface? 我应该将其作为通用接口实现吗?

In your code 在你的代码中

public abstract class CacheAble<T>{
   public abstract <T> boolean insertCacheAble(T data);
   public abstract <T> boolean deleteCacheAble(T data);      
}

the type parameter T of the methods is not the same T as the class type parameter. 类型参数T的方法是一样的T作为类类型参数。 That's probably not what you want. 那可能不是您想要的。 Firstly, it makes the methods more generic than you want (you want their signature to be fixed, if you have fixed the class' type parameter). 首先,它使方法的通用性超出了您的期望(如果您固定了类的type参数,则希望固定它们的签名)。 Secondly, that forces you to use a type parameter in the implementation of those methods in subclasses, even though they should work on a specific type. 其次,这迫使您在子类中的那些方法的实现中使用类型参数,即使它们应在特定类型上起作用。 So define it like this: 因此,如下定义:

public abstract class CacheAble<T>{
   public abstract boolean insertCacheAble(T data);
   public abstract boolean deleteCacheAble(T data);
}

Also, as "sodik" has pointed out, your subclass is specific to a certain type of T and therefore should no longer make any reference to T , but only to the specific type MyData . 同样,如“ sodik”所指出的那样,您的子类特定于T的特定类型,因此不再应引用T ,而仅引用特定的MyData类型。 Then you can use the public methods of MyData (like eg getters and setters for color and name): 然后,您可以使用MyData的公共方法(例如,颜色和名称的getter和setter):

public MyDataOps extends CacheAble<MyData>{
   @Override
   public boolean insertCacheAble(MyData data){
       // ... data.getName(); ...
       // ... data.getColor(); ...
   }

   @Override
   public boolean deleteCacheAble(MyData data){
       // ... data.getName(); ...
       // ... data.getColor(); ...
   }
}
String name = data.getName();
String color = data.getColor();

You can't access the fields directly since they are private. 您不能直接访问这些字段,因为它们是私有的。

@Override
   public <MyData> boolean insertCacheAble(MyData data){
       //... want to be able to Access MyData.name & MyData.color
       //... how can I do this?

      String name = data.name; // This doesn't work
      String color = data.color; // This doesn't work

      //.. insert db values
   }

T is not a class you have implemented with the private members of name or color. T不是您使用名称或颜色的私有成员实现的类。 MyData is valid however. MyData有效。 Replace your T object parameter with a MyData object and everything should work just fine. MyData对象替换您的T对象参数,一切都应该正常工作。

public class MyData{
    public Hashmap<String,Object> dataField;
    //... default constructor    

    //... setters and getters

}

... ...

@Override
   public boolean insertCacheAble(MyData data){


      String name = data.dataField.get("name"); 
      String color = data.dataField.get("color");

      //.. insert db values
   }

   let anObject be a <T> with field MyData myData
   insertCacheAble(anObject.myData);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM