java中如何遍历一个类的所有对象?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中如何遍历一个类的所有对象?相关的知识,希望对你有一定的参考价值。

今天看到一个循环for(Object o: numbers),他可以遍历numbers这个变量所含的所有对象,但当我把numbers改成一个类的时候就会出错,请问可不可以通过for语句遍历一个类的所有对象,不用for也行

你这里的numbers是一个对象数组,所以你可以这样遍历,单个对象是不行的。遍历对象内部成员,在反射里面有方法,我刚练习完,只有将对象的成员分解到数组中才行。分享给你了:
Class c=Class.forName("AbstractClassTest.Car"); //要包名+类名
Object o=c.newInstance();
Car car=(Car)o;
Field[] fields=c.getDeclaredFields();//拿到数据成员
Method[] methods=c.getMethods();//拿到函数成员
/*System.out.println(fields.length);
System.out.println(methods.length);*/
for(Field f : fields)
System.out.println("该类的内部变量有:"+f.getName());

for(Method m : methods)
System.out.println("该类的方法有:"+m.getName());
参考技术A 什么叫做遍历一个类的所有对象?

如果要查找当前运行环境下一个类的所有对象实例,这个功能是无法用java语言来完成的。只有部分虚拟机可以输出当前内存下所有对象实例,这也仅仅是为了调试(Profile)。

如果是遍历指定对象实例的所有对象属性?这个得用反射来实现。
参考技术B JAVA反射机制定义:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
找找这方面的资料,应该就是你要的结果。

参考资料:百度百科

参考技术C 用 apache BeanUtils 包中的一个 BeanMap 的类,这个类可以把一般的
JAVABean 中属性和 属性值 转化到 一个Map 中。到时候 你就可以利用 for 循环调用了。

BeanMap map = new BeanMap(you_Class_Instance);
for(String key:map.keyset())
map,get(key);//key 是属性,map.get(key) 是属性值。

先要去找到 BeanUtils的包才能用
参考技术D 它这个numbers为容器,数组,里面存储的是对象,这是java的foreach语法;
你想要遍历一个类的所有对象,也只有用instanceof来一个一个的判断了,反射里不知道有没有现成的。。。

在Java中遍历父类的ArrayList时使用Subclass方法

【中文标题】在Java中遍历父类的ArrayList时使用Subclass方法【英文标题】:Using Subclass method when iterating through ArrayList of parent class in Java 【发布时间】:2013-01-03 11:33:49 【问题描述】:

在这个循环中,我正在遍历 Entity 类型的 ArrayList,其中包含 Entity 类型的对象以及 Projectile 类型的对象,后者扩展了 Entity。如果对象是 Projectile 的实例,我希望执行以下代码。但是,getVelocity() 方法仅在子类 Projectile 中,而不在 Entity 中。所以我无法编译下面的代码。

我可以想办法解决这个问题,例如使用单独的 ArrayList。但是,关键是将所有实体保留在一个全局列表中,而不是将它们分开。这个问题有简单的解决方案,还是我需要改变我的代码结构?

for (Entity f: glo.getList()) 
           if (f instanceof Projectile)
              f.setX(f.getVelocity()/rawFPS);
        

【问题讨论】:

【参考方案1】:

这似乎是一个循环,在游戏引擎的每一次滴答声中都会以某种方式更新您的实体。

在我看来,更清洁的解决方案是:

class Entity 
  ...
  public void update() 
  ...


class Projectile extends Entity 
  ...
  @Override
  public void update() 
    setX(velocity/rawFPS);
  
  ...

我不知道您的架构,您可能需要也可能不需要将rawFPS 传递给update()。 (正如@Naveen 非常正确地指出的那样,这不是很干净,所以如果可以的话,请避免使用它)。此外,如果您的 Entity 是抽象的,本身没有任何功能,请首先考虑将其设为 interface

【讨论】:

+1 这是一个很好的面向对象的方法。让对象在知道如何更新/渲染时自行更新/渲染,必要时可以通过使用内部/非标准 API 受益。 我没有想过拥有独立的更新方法。鉴于我的其余代码,我将研究它是否可行。 嗯...将rawFPS 传递给所有实体闻起来有点奇怪,因为大多数Entitys 会忽略它。 @Navin 好吧,这取决于。在游戏中,大多数需要更新的实体都会根据经过的时间进行更新,因此实际上大多数实体都需要rawFPS。但我同意你的看法:如果可以,最好避免这种情况。 传递更新程序并使用特定于类型的回调。这将使它成为非常接近访客模式的双重调度。【参考方案2】:

您必须将其转换为 Projectile 才能编译。试试这个:

for (Entity f: glo.getList()) 
           if (f instanceof Projectile)
              f.setX(((Projectile)f).getVelocity()/rawFPS);
        

这是因为 java 总是检查对象声明的类型;在您的情况下,这是Entity

您可能想要添加一个@SuppressWarnings("unchecked"),以便您的 IDE 和阅读您的代码的任何人都知道未经检查的强制转换是故意的。

【讨论】:

【参考方案3】:

即使if(f instanceof Projectile) 是真的,你的引用是Entity 类型的,它不知道你在子类中声明了什么,所以编译失败

Entity 类中提供具有相同签名的空白方法,而不是在子类中提供 override 并删除 instanceof 检查,如果它适合您的类模型

使用强制转换

if(f instanceof Projectile)
  ((Projectile)f).setX(..);

【讨论】:

【参考方案4】:

Entity 确实应该是一个interface,并在其上定义了一个getVelocity() 方法。当然,您可以解决问题并进行投射,但请问问自己,对于您正在构建的内容,正确的逻辑模型是什么。

【讨论】:

我不是反对者,但我猜这是因为Entity 可能没有速度,所以给它一个getVelocity() 是没有意义的。【参考方案5】:

说真的,伙计们?很烂的例子。每一个 Java 指南都会告诉你这一点。

这里出了点问题:您正在循环一组实体并使用另一个数据项 FPS 更改子集(子类实例)的内部状态。如果您在构建 Projectile 时没有 FPS,那么稍后让这个外部类注入它似乎有点随机。只在 FPS 上调用一个集合然后更新位置可能会更干净。

外部类可能只需要 Projectiles。

【讨论】:

instance of sucks 真的吗?这个问题正是你使用instance of的那种情况。 我倾向于同意 Rob 的观点,instanceof 确实很烂。我没有在回答中提到那部分。 嗯...为什么是suck? 因为它不是面向对象的。如果您使用的是实例,则您的模型有缺陷。 第二个链接,老兄:来自 Google 的javapractices.com/topic/TopicAction.do?Id=31。

以上是关于java中如何遍历一个类的所有对象?的主要内容,如果未能解决你的问题,请参考以下文章

C++遍历获得一个类的所有属性名,对该类的实例的所有属性的值 ...~~

java 遍历 类属性的属性值

Java递归遍历集合

如何遍历一个JS对象中的所有属性

在Java中遍历父类的ArrayList时使用Subclass方法

Java中如何遍历Map对象的4种方法