- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试创建一个类来代表一副牌。然而,我想以一种可以是任何类型的牌的方式创建它,它不需要知道它是哪种类型,只需能够存储它们,洗牌并一次绘制一张牌,就可以是uno牌,普通扑克牌,或交易卡。为此,我一直在尝试一些我听说过但没有使用过的东西——泛型。
但是,我根本没有运气让它发挥作用。它不会实例化、填充卡片或在绘制卡片时返回正确的类型。我尝试过混合和匹配,但就是无法让它发挥作用。
有问题的旧代码已被截断以节省空间,请查看以前的编辑以查看。摘要:我使用 Cardable 而不是 T,并且缺乏一般性的泛型表达。
那么这将如何工作,我对泛型完全陌生。我四处寻找,不断听说类型删除,并且类文字应该是一个参数,yadda yadda...但是 ArrayList 是如何做到的呢?为什么你可以直接输入 ArrayList<String>()
它会正常工作,而不需要像 ArrayList<String>(String.GetClass())
这样可笑的东西。 ?
感谢您的宝贵时间。
编辑:Cardable 是一个类,任何可以放入牌组的卡牌都会扩展。
Edit2:感知的建议因此修复了我的代码,但我不确定如何调用来填充甲板。现在我用它来接受一个数组,但最好将它放在内部,而且我不完全确定我掌握了整个工厂方法。
public class Deck<T extends Cardable>
{
private ArrayList<T> cardsInDeck;
public Deck()
{
cardsInDeck = new ArrayList<T>();
}
public void populate( T[] newCards )
{
cardsInDeck.clear();
for( T card : newCards )
{
cardsInDeck.add( card );
}
shuffle();
}
public T drawCard()
{
T card = null;
try
{
card = cardsInDeck.get( 0 );
}
catch( IndexOutOfBoundsException e )
{
System.out.println( "Ran out of Cards" );
e.printStackTrace();
}
cardsInDeck.remove( 0 );
return card;
}
public void shuffle()
{
ArrayList<T> newDeck = new ArrayList<T>();
Random rand = new Random();
while( !cardsInDeck.isEmpty() )
{
int index = rand.nextInt( cardsInDeck.size() );
newDeck.add( cardsInDeck.get( index ) );
cardsInDeck.remove( index );
}
cardsInDeck = newDeck;
}
public int getSize()
{
return cardsInDeck.size();
}
}
最佳答案
事情是: ArrayList<E>
的实现不依赖于实际类型 E。这就是为什么您不需要在构造函数中传递类型(如您所说, new ArrayList<String>(String.class)
)。
如果您编写一个泛型类,由于某种原因,必须在运行时确切地知道泛型类型代表什么,那么您需要在构造函数中传递该类型,因为,正如您所说,类型删除 不允许您从 T
获取类(class)。你需要new MyClassThatNeedToKnowItsActualTypeParameter<String>(String.class)
.
例如,假设有一个类访问数据库并检索给定类的实例。类的实例存储在以该类命名的表中。例如:
class MyRepository<T> {
T load(int id) { ... }
}
方法load
需要在运行时确切地知道 T 是什么,因为它需要能够构造一个查询,该查询将使用 T 代表的实际类的名称。然而,在Java中,您无法从T
获取此信息。 ,自 T
将因类型删除而消失。此外,load
方法需要一种方法来创建正确类型的实例并将数据从数据库写入其中。要创建类的实例,您可以使用反射,执行 clazz.newInstance()
例如。在这里,再次强调,您需要确切地知道您正在处理的是什么类别。你最终会得到这样的结果:
class MyRepository<T>
private final Class<T> clazz;
MyRepository(Class<T> clazz) { this.clazz = clazz; }
T load(int id) {
final String tableName = clazz.getSimpleName() + "Table";
/* connect, retrieve data, disconnect */
final T t = clazz.newInstance(); // must be inside try/catch
/* fill instance t with data from database somehow (using reflection probably, which, again, needs to know what clazz is */
return t;
}
}
...
final MyRepository<User> userRepository = new MyRepository<User>(User.class);
final User user = userRepository.load(123);
...
关于java - 泛型并调用属于该类型的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14301082/
我是一名优秀的程序员,十分优秀!