java静态代码块初始数组
时间: 2024-06-20 18:01:55 浏览: 13
在Java中,静态代码块(Static Initializer Block)是一种特殊类型的初始化块,它在类加载时执行,通常用于执行那些只在类首次被加载时需要执行一次的初始化操作,比如创建并初始化静态成员变量,包括数组。静态代码块在类的作用域内,不依赖于任何特定的对象实例。
如果你想要初始化一个静态数组,可以在静态代码块中完成,例如:
```java
public class MyClass {
// 静态代码块
static int[] myArray; // 声明静态数组
static {
// 初始化静态数组
myArray = new int[10]; // 创建一个长度为10的整型数组
for (int i = 0; i < myArray.length; i++) {
myArray[i] = i; // 将数组元素填充为0到9
}
}
// 类的其他方法和属性...
}
```
在这个例子中,`myArray`数组会在`MyClass`第一次被加载时自动初始化。如果需要在程序运行过程中改变数组内容,因为它是静态的,所以必须确保只有一次初始化,并且在初始化后保持不变。
相关问题
java完整的SM4Utils工具类代码
以下是一个Java完整的SM4Utils工具类代码,可以用于加密和解密数据:
```java
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
public class SM4Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final String ALGORITHM_NAME = "SM4";
private static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
private static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS7Padding";
private static final int DEFAULT_KEY_SIZE = 128;
/**
* ECB加密
*
* @param data 待加密数据
* @param secretKey 密钥
* @return 加密后的数据
* @throws Exception 加密异常
*/
public static String encryptECB(String data, String secretKey) throws Exception {
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
// 加密模式
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, ALGORITHM_NAME));
byte[] encrypted = cipher.doFinal(dataBytes);
return byte2Hex(encrypted);
}
/**
* ECB解密
*
* @param encryptedData 待解密数据
* @param secretKey 密钥
* @return 解密后的数据
* @throws Exception 解密异常
*/
public static String decryptECB(String encryptedData, String secretKey) throws Exception {
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
byte[] encryptedBytes = hex2Byte(encryptedData);
// 解密模式
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, ALGORITHM_NAME));
byte[] decrypted = cipher.doFinal(encryptedBytes);
return new String(decrypted, StandardCharsets.UTF_8);
}
/**
* CBC加密
*
* @param data 待加密数据
* @param secretKey 密钥
* @param iv 初始化向量
* @return 加密后的数据
* @throws Exception 加密异常
*/
public static String encryptCBC(String data, String secretKey, String iv) throws Exception {
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8);
// 加密模式
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, ALGORITHM_NAME), new IvParameterSpec(ivBytes));
byte[] encrypted = cipher.doFinal(dataBytes);
return byte2Hex(encrypted);
}
/**
* CBC解密
*
* @param encryptedData 待解密数据
* @param secretKey 密钥
* @param iv 初始化向量
* @return 解密后的数据
* @throws Exception 解密异常
*/
public static String decryptCBC(String encryptedData, String secretKey, String iv) throws Exception {
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
byte[] encryptedBytes = hex2Byte(encryptedData);
byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8);
// 解密模式
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, ALGORITHM_NAME), new IvParameterSpec(ivBytes));
byte[] decrypted = cipher.doFinal(encryptedBytes);
return new String(decrypted, StandardCharsets.UTF_8);
}
/**
* 字节转十六进制字符串
*
* @param bytes 字节数组
* @return 十六进制字符串
*/
private static String byte2Hex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}
/**
* 十六进制字符串转字节数组
*
* @param hex 十六进制字符串
* @return 字节数组
*/
private static byte[] hex2Byte(String hex) {
int len = hex.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
result[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
}
return result;
}
}
```
这个工具类使用了Bouncy Castle密码库来实现SM4算法的加密和解密功能。在使用前,需要先将Bouncy Castle密码库添加到Java加密环境中,这里使用了static块来进行静态初始化。
其中,ECB模式和CBC模式各提供了加密和解密的方法,需要传入待加密/解密的数据、密钥和初始化向量(CBC模式需要)。在加密过程中,需要使用Cipher类来进行加密/解密操作,而密钥和初始化向量则需要使用SecretKeySpec和IvParameterSpec类来进行封装。最后,将加密/解密后的结果转换成十六进制字符串进行返回即可。
另外,这个工具类还提供了将字节数组转换成十六进制字符串和将十六进制字符串转换成字节数组的两个辅助方法,用于在加密/解密过程中进行数据的转换。
Cause: java.lang.NullPointerException
java.lang.NullPointerException是Java中常见的运行时异常之一,表示空指针异常。它通常在以下情况下发生:
1. 对一个空对象调用方法或访问属性。
2. 将null赋值给一个非空对象。
3. 在数组中使用null索引。
解决java.lang.NullPointerException的方法如下:
1. 检查空引用:在代码中检查可能出现空引用的地方,并在使用前判断是否为null。可以使用if语句或者三目运算符进行判断。
2. 检查调用方法的参数:如果是调用方法出现了NullPointerException错误,可以检查传递给方法的参数是否为null。在方法中使用断言或者if语句进行判断。
3. 检查类的初始化:如果是在类的构造函数或者静态初始化块中出现了NullPointerException错误,可以检查类的初始化是否正确。检查类中的变量是否被正确初始化,是否有空指针异常。
4. 使用Optional类:Java 8引入了Optional类,可以避免空引用的问题。使用Optional类,可以将可能为空的变量包装在Optional对象中,然后使用Optional类的方法进行操作。
5. 使用断言:可以使用断言对空引用进行检查,如果为空则抛出异常。在Java中使用assert语句进行断言。
6. 使用日志:使用日志记录空引用的位置和原因,有助于快速定位和解决问题。
综上所述,避免空引用是解决java.lang.NullPointerException错误的最有效方法[^1]。