java类编写和对象构造

时间:2013-01-09 18:45:41

标签: java bytearray

这是关于编写java类以及它们如何实例化的一般性问题。

public class transaction
{
    int amount;
    char ref;
}

如果一个类是这样写的那么它可以像结构一样使用。然后,当数据作为数据报中的byte []通过网络传输时,它将转换为事务对象。一个地方是在一个单独的类中,比如说:

public class doStuff
{
    static transaction t; // the int and the char are alloc'd onto the DataSegment

    public static transaction fromByte(byte[] buf)
    {
        t = new transaction(); // make sure t is null to begin with (on the heap)
        t.ref = ''; // initialise char (to avoid null bytes)

        t.amount = ByteBuffer.wrap(buf).getInt();
        t.ref = ByteBuffer.wrap(buf).getChar();

        return t;
    }
}

然后另一个类调用doStuff,如下所示:

import doStuff;    

class otherClass extends Thread
{
    static transaction x = new transaction();

    ... in the run method
    x = doStuff.fromByte(buf);
    ...
}

但是现在我想把类数据和方法放在一个地方(据说应该是这样?)所以不要在doStuff类中使用fromByte(byte [] buf)方法,而是将它移到事务类中。所以事务类现在看起来像这样:

public class transaction
{
    int amount;
    char ref;

    static transaction t;

    public static transaction fromByte(byte[] buf)
    {
        t = new transaction(); // make sure t is null to begin with
        t.ref = ''; // initialise char (to avoid null bytes)

        t.amount = ByteBuffer.wrap(buf).getInt();
        t.ref = ByteBuffer.wrap(buf).getChar();

        return t;
    }
}

然后在otherClass中我使用:

import transaction;

class otherClass extends Thread
{
    static transaction x = new transaction();

    ... in the run method
    x = fromByte(buf);
    ...
}

表面上它都具有与以前相同的效果。

我的问题是:在事务数据(amount和ref)上添加了操作fromByte(byte[] buf)transaction类后,实例化transaction对象的开销发生了变化。如果每秒有数百个来自网络的事务,那么将fromByte(byte[] buf)方法添加到transaction类意味着当它在doStuff类中实例化时,将使用比之前。换句话说,每次int类生成char时,不是简单地生成doStufffoo(作为数据段上的静态变量),而是在堆(我认为,而不是数据段),并且fromByte(buf)方法被推送到堆栈然后transaction类再次在数据段上递归调用自身(静态变量)...

好吧,看起来有点混乱。有没有更好的方法将数据和方法放在同一个类中并保持最大速度?它可以克服递归变量调用(fromByte方法返回一个事务对象,并且'int / char'形式中的确定)任何注释? : - )

2 个答案:

答案 0 :(得分:1)

这将从buf开始两次读取。

    t.amount = ByteBuffer.wrap(buf).getInt();
    t.ref = ByteBuffer.wrap(buf).getChar();

我怀疑你的意思

    ByteBuffer bb = ByteBuffer.wrap(buf);
    t.amount = bb.getInt();
    t.ref = bb.getChar();
  

将事务数据(amount和ref)上的操作fromByte(byte [] buf)添加到事务类中,然后实例化事务对象的开销发生了变化。

每次创建byte[]ByteBuffer也是一种开销。

  

换句话说,每次doStuff类生成foo时,不是简单地生成int和char(作为数据段上的静态变量),而是在堆上生成(我认为,而不是数据段)将fromByte(buf)方法推送到堆栈然后事务类再次在数据段上递归调用自身(静态变量)......

如上所述,创建transaction obejct可能只是您开销的一小部分。例如。从Socket读取最多只需要100倍。

  好吧,看起来有点混乱。有没有更好的方法将数据和方法放在同一个类中并保持最大速度?

不要使用byte[],每次都不要创建新的ByteBuffer,也不要每次都创建新的transaction对象。您可以提前创建这些对象,也可以不创建它们。然后重复使用它们。

例如,考虑在建立连接(或回收一个连接)时创建一个 direct ByteBuffer并解码消息并调用一个监听器

interface TransactionListener {
    public void onTransaction(int num, char status);
}

这样就不会在堆栈上创建任何对象。

在这种情况下,您的性​​能瓶颈将是从Socket读取,具体取决于您对此信息的处理方式。 ;)

答案 1 :(得分:1)

就性能而言,两种方法之间的唯一区别是调用静态方法的成本。这是一个非常微不足道的成本,并且由JIT编译器进一步降低。

就封装而言,问题在于您是否希望将transaction类的知识放在doStuff类中,或者是否要将字节流结构的知识放入{{1} } .class。无论如何都有争论。