Java如何扩展/包装内置类



我是Java语言的新手,我尝试编写我的第一个相对复杂的程序。写了几堂课后,我意识到我几乎不使用内置的课程(例如BigInteger,Messagedigest,Bytebuffer),因为它们不完全满足我的需求。取而代之的是,我写自己的课,在课堂内我使用内置类作为属性。示例:

public class SHA1 {
    public static final int SHA_DIGEST_LENGTH = 20;
    private MessageDigest md;
    public SHA1() {
        try {
            md = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
    public void update(byte[] data) {
        md.update(data);
    }
    public void update(BigNumber bn) {
        md.update(bn.asByteArray());
    }
    public void update(String data) {
        md.update(data.getBytes());
    }
    public byte[] digest() {
        return md.digest();
    }
}

使用以下简单类,我不必在使用SHA1时使用catch,我可以将自定义的bignumber类作为参数,我也可以将字符串作为参数以更新功能。

以下Bignumber类包含我需要的所有功能以及我的需求。

public class BigNumber {
    private BigInteger m_bn;
    public BigNumber() {
        m_bn = new BigInteger("0");
    }
    public BigNumber(BigInteger bn) {
        m_bn = bn;
    }
    public BigNumber(String hex) {
        setHexStr(hex);
    }
    //reversed no minsize
    public byte[] asByteArray() {
        return asByteArray(0, true);
    }
    //reversed with minsize
    public byte[] asByteArray(int minSize) {
        return asByteArray(minSize, true);
    }
    public byte[] asByteArray(int minSize, boolean rev) {
        byte[] mag = m_bn.toByteArray();
        //delete sign bit
        //there is always a sign bit! so if bitNum % 8 is zero then
        //the sign bit created a new byte (0th)
        if(getNumBits() % 8 == 0) {
            byte[] tmp = new byte[mag.length-1];
            System.arraycopy(mag, 1, tmp, 0, mag.length-1);
            mag = tmp;
        }
        //extend the byte array if needed
        int byteSize = (minSize >= getNumBytes()) ? minSize : getNumBytes();
        byte[] tmp = new byte[byteSize]; 
        //if tmp's length smaller then byteSize then we keep 0x00-s from left
        System.arraycopy(mag, 0, tmp, byteSize-mag.length, mag.length);
        if(rev) ByteManip.reverse(tmp);
        return tmp;
    }
    public String asHexStr() {
        return ByteManip.byteArrayToHexStr(asByteArray(0, false));
    }
    public void setHexStr(String hex) {
        m_bn = new BigInteger(hex, 16);
    }
    public void setBinary(byte[] data) {
        //reverse = true
        ByteManip.reverse(data);
        //set as hex (binary set has some bug with the sign bit...)
        m_bn = new BigInteger(ByteManip.byteArrayToHexStr(data), 16);
    }
    public void setRand(int byteSize) {
        byte[] tmp = new byte[byteSize];
        new Random().nextBytes(tmp);
        //reversing byte order, but it doesn't really matter since it is a random
        //number
        setBinary(tmp);
    }
    public int getNumBytes() {
        return (m_bn.bitLength() % 8 == 0) ? (m_bn.bitLength() / 8) : (m_bn.bitLength() / 8 + 1);
    }
    public int getNumBits() {
        return m_bn.bitLength();
    }
    public boolean isZero() {
        return m_bn.equals(BigInteger.ZERO);
    }
    //operations
    public BigNumber modExp(BigNumber exp, BigNumber mod) {
        return new BigNumber(m_bn.modPow(exp.m_bn, mod.m_bn));
    }
    public BigNumber mod(BigNumber m) {
        return new BigNumber(m_bn.mod(m.m_bn));
    }
    public BigNumber add(BigNumber bn) {
        return new BigNumber(m_bn.add(bn.m_bn));
    }
    public BigNumber subtract(BigNumber bn) {
        return new BigNumber(m_bn.subtract(bn.m_bn));
    }
    public BigNumber multiply(BigNumber bn) {
        return new BigNumber(m_bn.multiply(bn.m_bn));
    }   
}

我的问题是,在Java语言中使用这类类而不是内置类是多么普遍?这是否使我的代码无法用于其他程序员(与实施内置类实施所有内容相比)?

我已经读到,新的C 程序员拼命尝试编写用来编写C的代码,因此C 的好处仍然隐藏起来。恐怕我在Java中做类似的事情:尝试自己实施所有内容,而不是直接使用Build-In类。这是在发生(例如在Bignumber类中)?

谢谢您的意见!

我通常编写一个实用程序类,该类将支持我处理逻辑。例如

public class CommonUtil{
  public byte[] asByteArray(int minSize)
  {
    return "something".getBytes();
  }
  // add more utility methods
}

包装一类时,当您通过这样做添加一些值时。如果要添加较小的功能,则值得使用实用程序类,而不是包装现有的类别。

我认为,如果您没有一个很好的理由再次实现相同的功能,则不应这样做。以下是几个原因:

  • 内置类都被世界各地的许多人使用,因此与您的代码相比,错误
  • 中的错误少。
  • 在Java中经历的用户在使用标准课程中比您的课程更好,他们需要更少的时间来理解您的代码并在项目中写一些新内容
  • 内置类具有良好的文档,因此使用它们更容易
  • 您正在通过实施Java专业人员实施和测试的内容来浪费时间。最好专注于自己的项目
  • 如果您正在编写一个长期项目,则需要支持所有课程。Oracle已经支持内置类。让他们完成工作!
  • 最后但不是最不重要的。您确定您对问题的了解比内置班级的作者更多吗?只有答案是肯定的,请考虑编写自己的实施。即使是每日使用的类的实施,例如收藏或与时间相关的类也很棘手。

您不会通过为您做这些东西的班级来获得任何东西。如果您要进行某些操作很多,那么您可能需要使用静态方法创建一个新的类,这些方法为您做这些重要的事情。

让我们假设您始终想要一个排序的数组。您可以举办一个新课程,我们称其为SortedArray。每当添加某些内容时,您都可以对其进行排序,但是当您只能添加所有内容然后调用(实用程序)方法阵列时,为什么要这样做呢?对于常见的操作,请看一下Java的数组类 - 如果您经常做某事,那就是您制作的方法,例如搜索和排序。就您而言,您可能会制作一种实用方法,将BigInteger变成一个字节阵列。您不应该只是制作自己的"更好"版本,可以做自己想要的。当其他人查看您的代码时,当您使用标准对象时,它会好得多,而不是拥有真正没有做任何事情的自定义对象。

正如@shark所说的,创建自己的解决方案是没有意义的,因为:

  1. 他们需要时间来创建
  2. 他们变得不那么灵活

但是,您可以扩展类(建议使用)或使用可能更适合您的第三方框架。

最新更新