假设我有一个空类叫做 ClsA()
,它的一个子类称为 ClsB()
像这样:
public static class ClsA {}
public static class ClsB extends ClsA {}
假设我们现在有一个clsa类型对象的arraylist,我想计算arraylist中有多少元素实际上是clsa或clsb类型的。通过一些搜索,我发现以下函数非常有效:
public static <T> int countInstances(ArrayList<?> list, Class<T> cls) {
int count = 0;
for(Object o : list) {
if(cls.isInstance(o)) {
count++;
}
}
return count;
}
实际上,下面的示例main方法确实给出了正确的输出。
public static void main(String[] args) {
// write your code here
ArrayList<ClsA> test = new ArrayList<>();
test.add(new ClsA());
test.add(new ClsB());
test.add(new ClsA());
test.add(new ClsB());
int result = countInstances(test,ClsB.class);
System.out.println(result);
}
但是,假设clsb现在定义如下:
public static class ClsB extends ClsA {
private final String type;
public ClsB(String type) {
this.type = type;
}
public String getType() {return type;}
}
我现在要计算给定arraylist中存在多少特定类型的clsb示例。在登记我的 countInstances()
如果一个元素属于给定的类(在本例中为clsb),我还希望能够检查给定给方法的类型是否与元素的类型匹配。有没有什么方法可以让你 Object o
因为编译器并不真正知道它的实际类型,所以将其转换为给定类的示例?
到目前为止我已经到了这一步:
public static void main(String[] args) {
// write your code here
ArrayList<ClsA> test = new ArrayList<>();
test.add(new ClsA());
test.add(new ClsB("t1"));
test.add(new ClsA());
test.add(new ClsB("t2"));
int result = countInstances(test,ClsB.class,true,"t1");
System.out.println(result);
}
public static <T> int countInstances(ArrayList<?> list, Class<T> cls, boolean checkForType, String type) {
int count = 0;
for(Object o : list) {
if(cls.isInstance(o)) {
if(!checkForType) count++;
else {}// somehow cast o into the given class (?)
}
}
return count;
}
2条答案
按热度按时间zbwhf8kr1#
是的,有
cls.cast(o);
它会做到的,会给你一个T
(因为cls
是Class<T>
,和cast(Object o)
方法j.l.Class
定义为返回T
. 它的行为就像cast操作符一样,因为它什么也不做:它只是Asserto实际上是这个类的一个示例(因此,创建为new This()
或者new SomeSubtypeOfThis()
). 如果是,它什么也不做。如果不是,则抛出classcastexception。在任何情况下都不会发生转换。这没用;毕竟,t仍然只是一个物体。这不会给你打电话的权力
getType()
在你的o
-因为T
没有界限,t除了java.lang.Object
已经有了。一般来说,你所从事的是结构类型:不管是什么
ClsB
重要的是,它有一个名为getType
.这很糟糕。
这意味着
public interface Camera { public void shoot(Person p); }
以及public interface Gun { public void shoot(Person p); }
在这样一个系统中,你是可以互换的,因此你会意外地把某人的头打掉。类型(类、接口等)不受此问题的影响,因为它们有一个名称空间-一个包头,这使它们有效地唯一。因此,一个方法不应该被认为有任何意义,除非该方法是在它所处类型的上下文中。
因此,你能做的,是这样的:
对于包含一个clsa示例和一个clsb示例的列表,上面将返回“2”,然后您通过
ClsA.class
作为第二个参数。毕竟,里昂证券的一个示例也是里昂证券的一个示例。
如果您正在寻找“1”的答案,那么您正在寻找:
然后对于“gettype”方法,我们必须将该方法链接到实际类型,因为否则你就是在打人,这很糟糕。所以,我把
getType()
方法,然后我们要求您传递一个clsa的列表:请注意,可以使用
ArrayList<ClsA>
或者一个ArrayList<ClsB>
-两者都可以。<? extends ClsA>
使之成为可能;这个? extends
这很重要。没有它,new ArrayList<ClsB>()
无法作为第一个参数传递。如果你想把这两个想法结合起来,那就是。。一种奇怪的关注点和声音的混合,听起来像是在java中使用结构化类型的概念,或者是一些黑客试图实现动态类型。停止那样做;java不是那种语言,它会一直伤害到我们,最终的结果会是非惯用的、难以维护的和难以阅读的代码。找到一种java风格的方法来做你正在做的事情。但是,不要说我没有警告你:
试图一概而论是没有意义的
ClsA
在这里,因为这样做可以消除代码实现这一点的能力ClsA
示例具有getType()
方法。yyhrrdl82#
这个怎么样(请参见countinstances的更改签名)。
这不回答你的职位的标题,但我猜这是你正在寻找的。