我是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时使用try catch,我可以将自定义BigNumber类作为参数,我也可以将String作为参数来更新函数。
以下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中做类似的事情:尝试自己实现所有内容而不是直接使用内置类。 这是发生了吗(例如在BigNumber类中)?
感谢您的意见!
答案 0 :(得分:3)
我通常会编写一个实用程序类来支持我处理逻辑。如
public class CommonUtil{
public byte[] asByteArray(int minSize)
{
return "something".getBytes();
}
// add more utility methods
}
答案 1 :(得分:2)
通过这样做来添加一些值时,包装类是有意义的。如果要添加小功能,则可以使用Utility类而不是包装现有类。
答案 2 :(得分:1)
我认为如果你没有很好的理由再次实现相同的功能,你不应该这样做。原因如下:
答案 3 :(得分:1)
你没有通过为你做这个东西的课程来获得任何东西。如果您要进行大量的某些操作,那么您可能希望使用静态方法创建一个新类,为您执行这些重要操作。
假设您始终需要排序数组。你可以创建一个新类,我们称之为SortedArray
。你可以在添加内容时对其进行排序,但是当你可以添加所有内容然后调用(实用程序)方法Arrays.sort时,为什么要这样做呢?
对于常见操作,请查看Java的Arrays类 - 如果您经常执行某些操作,那么您可以使用这种方法,例如搜索和排序。在您的情况下,您可以创建一个实用程序方法,将BigInteger转换为字节数组。你不应该只是制作自己的,“更好”的版本来做你想要的。当其他人查看您的代码时,当您使用标准对象时,它会更好,而不是custom objects that don't really do anything。
答案 4 :(得分:0)
正如@Shark评论的那样,创建自己的解决方案毫无意义,因为:
但是,您可以扩展类(建议使用它)或使用可能更适合您的第三方框架。