有一些数据,希望将他们放置到一个容器中,以便在方法调用时进行传递~ Java 本身提供了一些结合类,如 List 或 Map 。那么在封装这些数据的时候,如果我自己创建一个容器(自定义一个类),那么在以该容器为参数的方法内,获取容器的内的数据时。可能更直接更直观(直观的调用该容器中获取某个数据的相关 get 方法)。这样一来比使用 List 或 Map 更具有针对性(毕竟我自己创建的类是针对程序中的数据或或业务需求所抽象出来的),更贴近面向对象的理念,而且使用起来...呵呵该怎么说呢.. 我感觉使用起来比 List 或 Map 要舒服的多。在程序编写的时候还有很多情况会遇到这个的问题:“是否需要为你的业务实现多创建一个类”。当然这样的困惑不仅仅局限于“是否需要多创建一个 VO ”。有的时候在一个类中能完成的任务,往往会根据需要(例如解耦合,等等),多创建一个活多个类去完成。问题:“在 Java 中创建一个类会带来程序运行的负担?”例如:内存的增长。用 VO 举例就是:使用我自己创建的 VO 是否要比直接使用 Map 或 List 多消耗一部分内存?容器内的数据肯定都是一样的,无论是使用自定义类还是 Map 或 List 都将占用同样的内存。关键在于类本身。是不是一个程序内如果包含的类多了,运行时就会造成更多的消耗呢?个人觉得不太可能如果多建一个类就会给程序运行增加一些负担,那么 Java 应该没人用了。可是就是有些人要说,少一个类要比多一个类效率要高,使用的内存要少。故此一问。坛友们不要从程序设计的角度上说“要不要多建一个类啊”。这里我只想知道。多建一个类对程序性能的影响。谢谢了啊

解决方案 »

  1.   

    创建一个类肯定会用掉内存空间,这是毋庸置疑的。我不是很明白 VO 如何使用 Map 或者 List 来替换?能否举个例子?
      

  2.   

    那就是说能不使用就不使用了?有些不解,不信~~~呵呵。Java 本身是鼓励通过创建自己的类去解决问题的啊,这不也是面向对象的需要么?
    我说的是 Value Object 就是普通的 JavaBean 。可以用 Map 来替换。
    VO:String username;
    String address;
    public String setUsername(){}
    public String getUsername(){}
    ..Map:
    map.put("username","hello");
    map.get("username");
      

  3.   

    这么跟你说吧,一个 Map 比一个普通的 POJO 类占用更大的内存空间,因为除了维护用户 put 到 Map 中的数据之外,还得维护 Map 内部的数据结构。如果都把值塞到 Map 里面,由于各种 VO 中数据类型不一定都是一样的,还将造成类型不安全,带来不必要的麻烦。如果 VO 中的一个数据类型由 String 改为了 Integer,用 Map 的话错误只会在运行期报出,而不会在编译期报出。而且 POJO 的话,将会直接在编译期报出错误。再者,如果所有的 POJO 都采用 Map 的话,那么很多的方法参数可能会是这样的:public Map<String, Object> addUser(<Map<String, Object> user);
    这里的一个 Map<String, Object> 表示一个 User 的数据,另外还有这样的:public Map<String, Object> addBook(<Map<String, Object> book);
    这里的一个 Map<String, Object> 表示一个 Book 数据。我不知道你看到这样的代码会有什么感觉?这样的话,我可以把一个 User 的 Map 数据作为 addBook 的参数进行调用,可想而知是很明显不正确的!而且这种不正确只能在运行期发生,并不会在编译期发生。这样做,除了数据类型不安全之外,这样使用带来的隐患可能是无穷无尽的。程序设计中应尽量将运行期的错误推前到编译期,也就是说能在编译期解决的问题,永远不要放到运行期去解决,这才是良策。
      

  4.   

    你可以实现List等接口,定义自己的集合对象。
      

  5.   

    个人感觉直接建反而更好
    我一般是不得不用的时候才用Java提供的容器
      

  6.   


    同意你的观点~~~不过......这么问吧:
        你说“创建一个类肯定会用掉内存空间,这是毋庸置疑的”。那么 the following:
    代码A:class ClassA{
        /**
         * username,age,address 是一个人的信息
         */
        public void method(String username,int age,String address){
            //operation
        }
    }
    代码B:class ClassA{
        /**
         * username,age,address 是一个人的信息
         */
        public void method(Person ps){
            //operation
        }
    }
    class Person{
        String username;
        int age;
        String address;
        get....
        set....
    }
    代码 B 比 代码 A 要多使用了一个类(我喜欢代码 B 。这样不仅数据好管理,而且在业务中逻辑会很清晰,而且.... 就是喜欢,呵呵 )。照你所说:“创建一个类肯定会用掉内存空间”, 那么代码 B 比代码 A 如何多使用的内存呢(什么时候使用的,被用来做什么)?又有多少呢? 不会在程序中要尽量减少自定义类吧?比较钻牛角尖的问题。呵呵~~~不好意思啦~~~我也不懈这样的问题,但每次自己想在代码中增加自己的类时,脑海里总有人说“这样影响性能”。哎~~~阴影啊~~~~呵呵~~~
      

  7.   

    楼主10楼的例子感觉是把耦合在 ClassA 里的东西给分离出来了
     
    本来就改那样做的吧这个性能没多大的影响的
    打个比方
    你去超市买东西 
    买的所有东西都装一个大袋子里

    你把东西分类装进几个小袋子再装到大袋子
    是没多大区别的
    并不会因为几个小袋子就要用个更大的袋子
      

  8.   

    这个要看业务规则了,如果就是一个确定的实体信息,当然用vo了,比如学生信息,可以有一个student的类,存储学生的学号,姓名,性别之类的,而你去查询学生信息的时候就是出来list么,或者特殊要求的再用学号当key,student做value构造map。
    很基础的模型呀,可以去多了解一下数据库持久层的框架,然后其他的地方可以比照建模。
      

  9.   


    啊~~“性能”这个词也许不过恰当,我只是想知道,这样多出来一个 Person 类后,对程序是否存在负面的影响。至于你的比方。我的理解:多声明一个类对程序时有影响的(使用的内存会多些,暂且这么理解吧,呵呵),但可以忽略。是这样吧?
      

  10.   


    存储相同的数据量,肯定vo消耗少,效率高,你看看Map的具体实现HashMap之类的代码就知道了,还有List的实现类ArrayList的源代码。
      

  11.   

    哎,站在设计的角度出发才是正确的,不要为犄角旮旯的东西太过关心。Java是面向对象,不是面向过程,要有一个面向对象的思想和设计。
      

  12.   


    能给说明一下,代码 B 比代码 A 所多消耗的内存,用在了什么地方呢?JVM 对 Person 的描述?类加载器对 Person 的加载?
      

  13.   

    很喜欢你这种刨根究底的学习方式我想代码B应该就是多了有关“类”的额外消耗部分,通用过程就是包括JVM对类的动态加载,连接和初始化的消耗,而代码A没有额外的数据结构需要维护与开销,是最直接的数据元
      

  14.   

    如果你认为这 8 个字节的空间很宝贵的话,那么整个项目所有的业务逻辑全部写在一个类的一个方法当中,也不要引用任何 jar 包,不要使用任何对象数据类型(含 String),全部使用那八个基本的数据类型。这样可以将内存占用小得不能再小了。如果你要那样做的话,没人反对。不过以后维护是你做的话你得苦死,不是你做的话你会被别人的口水淹死。内存空间是有价的,但是维护这些代码耗费的时间是用金钱换不回来的。算法中不是有这样的形式么:空间换时间!如果斤斤计较这些创建对象所耗费的内存空间,那么所有面向对象的语言均不适合做这些事情。用一堆的参数与包装成对象,只有 8 个字节内存空间的差别。
      

  15.   

    这里所指的是内存是 heap 内存,只有这一块空间是用于存放数据的。像栈内存、PermGen 内存等都是用于常量,以及类信息数据用的,这些内存除非加载了大量的类,否则很少会用尽。
      

  16.   

    To:火龙果多谢你深入了这个问题:),这儿我有个疑问,8个字节怎么来的,我查了下http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.htmlClassFile {
        u4 magic;
        u2 minor_version;
        u2 major_version;
        u2 constant_pool_count;
        cp_info constant_pool[constant_pool_count-1];
        u2 access_flags;
        u2 this_class;
        u2 super_class;
        u2 interfaces_count;
        u2 interfaces[interfaces_count];
        u2 fields_count;
        field_info fields[fields_count];
        u2 methods_count;
        method_info methods[methods_count];
        u2 attributes_count;
        attribute_info attributes[attributes_count];
    }类文件是由8位长的字节流所组成(A class file consists of a stream of 8-bit bytes.)
    那看这个结构也不像是只有8个字节
      

  17.   

        public static void main(String args[]) {
            int N = 100000;
            long n = Runtime.getRuntime().freeMemory();
            Test[] objs = new Test[N];
            System.out.println(n - Runtime.getRuntime().freeMemory());
            n = Runtime.getRuntime().freeMemory();
            for(int i = 0; i < N; i++) {
                objs[i] = new Test();
            }
            System.out.println(n - Runtime.getRuntime().freeMemory());
        }这样估算的。Java 中的 sizeof 没有意义。参考 JavaWorld 上的两篇文章:Sizeof for Java
    http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.htmlJava Tip 130: Do you know your data size?
    http://www.javaworld.com/javaworld/javatips/jw-javatip130.html
      

  18.   

    八个字节,一个是标记字,包含hash,垃圾收集标记,线程锁定信息;另一个字是指向class对象的指针。这是sun jvm的实现
      

  19.   

    具体多消耗多少内存,这个要看具体情况了,32位系统和64位系统的消耗就不一样,不同的jvm实现和垃圾回收算法,可能也会有所不同。
    但是效率就高在栈要比堆快,你越少使用对象,那你的程序效率肯定就越高,不过说来说去还是回到了面向对象设计的好处上来了,对于普通的应用,那点效率牺牲和内存消耗完全值得。
    提高效率可以通过其他的方法,优化算法,增加缓存等等。
      

  20.   

    Object overhead for "housekeeping" informationInstances of an object on the Java heap don't just take up memory for their actual fields. Inevitably, they also require some "housekeeping" information, such as recording an object's class, ID and status flags such as whether the object is currently reachable, currently synchronization-locked etc.
    In Hotspot:    * a normal object requires 8 bytes of "housekeeping" space;
        * arrays require 12 bytes (the same as a normal object, plus 4 bytes for the array length). Other JVMs probably have a similar object overhead. 的确,除了对象持有消耗以外,应该还是由类转化为对象的消耗,我是这样认为的