为什么我会得到;例外情况;必须被抓住或宣布被扔出去;当我试图编译Java代码时?
考虑:为什么我会得到;例外情况;必须被抓住或宣布被扔出去;当我试图编译Java代码时?,java,exception,Java,Exception,考虑: import java.awt.*; import javax.swing.*; import java.awt.event.*; import javax.crypto.*; import javax.crypto.spec.*; import java.security.*; import java.io.*; public class EncryptURL extends JApplet implements ActionListener { Container c
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.io.*;
public class EncryptURL extends JApplet implements ActionListener {
Container content;
JTextField userName = new JTextField();
JTextField firstName = new JTextField();
JTextField lastName = new JTextField();
JTextField email = new JTextField();
JTextField phone = new JTextField();
JTextField heartbeatID = new JTextField();
JTextField regionCode = new JTextField();
JTextField retRegionCode = new JTextField();
JTextField encryptedTextField = new JTextField();
JPanel finishPanel = new JPanel();
public void init() {
//setTitle("Book - E Project");
setSize(800, 600);
content = getContentPane();
content.setBackground(Color.yellow);
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
JButton submit = new JButton("Submit");
content.add(new JLabel("User Name"));
content.add(userName);
content.add(new JLabel("First Name"));
content.add(firstName);
content.add(new JLabel("Last Name"));
content.add(lastName);
content.add(new JLabel("Email"));
content.add(email);
content.add(new JLabel("Phone"));
content.add(phone);
content.add(new JLabel("HeartBeatID"));
content.add(heartbeatID);
content.add(new JLabel("Region Code"));
content.add(regionCode);
content.add(new JLabel("RetRegionCode"));
content.add(retRegionCode);
content.add(submit);
submit.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "Submit"){
String subUserName = userName.getText();
String subFName = firstName.getText();
String subLName = lastName.getText();
String subEmail = email.getText();
String subPhone = phone.getText();
String subHeartbeatID = heartbeatID.getText();
String subRegionCode = regionCode.getText();
String subRetRegionCode = retRegionCode.getText();
String concatURL =
"user=" + subUserName + "&f=" + subFName +
"&l=" + subLName + "&em=" + subEmail +
"&p=" + subPhone + "&h=" + subHeartbeatID +
"&re=" + subRegionCode + "&ret=" + subRetRegionCode;
concatURL = padString(concatURL, ' ', 16);
byte[] encrypted = encrypt(concatURL);
String encryptedString = bytesToHex(encrypted);
content.removeAll();
content.add(new JLabel("Concatenated User Input -->" + concatURL));
content.add(encryptedTextField);
setContentPane(content);
}
}
public static byte[] encrypt(String toEncrypt) throws Exception{
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
}
catch(Exception e){
}
}
public static byte[] decrypt(byte[] toDecrypt) throws Exception{
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] decrypted = cipher.doFinal(toDecrypt);
return decrypted;
}
public static String bytesToHex(byte[] data) {
if (data == null)
{
return null;
}
else
{
int len = data.length;
String str = "";
for (int i=0; i<len; i++)
{
if ((data[i]&0xFF) < 16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
}
public static String padString(String source, char paddingChar, int size)
{
int padLength = size-source.length() % size;
for (int i = 0; i < padLength; i++) {
source += paddingChar;
}
return source;
}
}
以及:
.java:109: missing return statement
如何解决这些问题?第一个错误
java.lang.Exception;必须捕获或声明为抛出字节[]加密=加密(concatull)
表示您的encrypt
方法抛出一个异常,该异常未由调用它的actionPerformed
方法处理或声明。在网站上阅读所有关于它的信息
您可以从中选择几个选项来编译代码
- 您可以从
方法中删除加密
,并在抛出异常
中实际处理异常加密
- 您可以从
中删除try/catch块,并将encrypt
和异常处理块添加到throws Exception
方法中actionPerformed
encrypt
)。方法中有一个return语句,但是如果抛出异常,则可能无法到达该语句,因此您需要在catch块中返回,或者从encrypt
中删除try/catch,正如我前面提到的。在actionPerformed(ActionEvent e)
中调用encrypt()
,它被声明为引发异常
。但是,actionPerformed
既不捕获此异常(在调用encrypt()
时使用try/catch),也不声明它本身抛出异常
然而,您的加密
方法并没有真正抛出异常
。它吞并了所有异常,甚至没有记录投诉。(糟糕的做法和糟糕的风格!)
另外,您的加密方法执行以下操作:
public static byte[] encrypt(String toEncrypt) throws Exception {
try{
....
return encrypted; // HERE YOU CORRECTLY RETURN A VALUE
} catch(Exception e) {
}
// YOU DO NOT RETURN ANYTHING HERE
}
也就是说,如果您捕获到任何异常,您会默默地丢弃它,然后从encrypt
方法的底部掉下来,而实际上不返回任何内容。这不会编译(如您所见),因为声明为返回值的方法必须为每个可能的代码路径返回值或引发异常。在“encrypt”方法中,您应该放弃try/catch,而是在调用encrypt的位置添加try/catch(在“actionPerformed”内)或者在encrypt内的catch内返回null(这是第二个错误。所有问题都源于此
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
包含在try,catch块中,问题是如果程序发现异常,您将不会返回任何内容。请这样说(根据程序逻辑修改):
对于第二个,您必须从encrypt方法调用中捕获异常,如下所示(也可以根据您的程序逻辑进行修改):
您必须从中吸取的教训:
- 具有返回类型的方法必须始终返回该类型的对象,我的意思是在所有可能的情况下
- 必须始终处理所有选中的异常
您需要决定如何处理encrypt
方法引发的异常
当前,encrypt
是用抛出异常
声明的-但是,在方法体中,异常被捕获在try/catch块中。我建议您:
- 从
加密
中删除抛出异常
子句,并在内部处理异常(考虑至少写一条日志消息);或者
- 从
encrypt
的主体中删除try/catch块,并用try/catch代替对encrypt
的调用(即在actionPerformed
中)
关于您提到的编译错误:如果在encrypt
的try
块中引发异常,则在catch
块完成后不会返回任何内容。您可以通过最初将返回值声明为null
来解决此问题:
public static byte[] encrypt(String toEncrypt) throws Exception{
byte[] encrypted = null;
try {
// ...
encrypted = ...
}
catch(Exception e){
// ...
}
return encrypted;
}
但是,如果您能够纠正更大的问题(异常处理策略),这个问题将自行解决—特别是如果您选择了我建议的第二个选项。问题在于此方法:
public static byte[] encrypt(String toEncrypt) throws Exception{
这是方法签名,大致上说:
- 方法名称是什么:加密
- 它接收的参数:一个名为toEncrypt的字符串
- 其访问修饰符:公共静态
- 如果调用时它可能会抛出一个异常
在本例中,方法签名表示,当调用此方法时,“可能”引发类型为“exception”的异常
基本上,在这种特殊情况下,您应该确保加密软件包在系统中可用
Java需要加密包的扩展,因此,异常被声明为“已检查”异常。当它们不存在时,由您来处理
在这个小程序中,如果加密包不可用,您将无法执行任何操作,因此您将在“开发”时检查。如果在您的程序运行时引发这些异常是因为您在“开发”中出错,则RuntimeException子类更合适
最后一行不再需要return语句,在第一个版本中,您捕获了异常,但没有对其执行任何操作,这是错误的
try {
// risky code ...
} catch( Exception e ) {
// a bomb has just exploited
// you should NOT ignore it
}
// The code continues here, but what should it do???
如果代码失败,最好
以下是一些相关的答案:
每次加密时,您应该生成不同的IV。IV不需要保密,只需将其传递给他人即可
public static byte[] encrypt(String toEncrypt) throws Exception{
byte[] encrypted = null;
try {
// ...
encrypted = ...
}
catch(Exception e){
// ...
}
return encrypted;
}
public static byte[] encrypt(String toEncrypt) throws Exception{
....
concatURL = padString(concatURL, ' ', 16);
byte[] encrypted = encrypt(concatURL); <-- HERE!!!!!
String encryptedString = bytesToHex(encrypted);
content.removeAll();
......
public static byte[] encrypt(String toEncrypt) {
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
} catch ( NoSuchAlgorithmException nsae ) {
// What can you do if the algorithm doesn't exists??
// this usually won't happen because you would test
// your code before shipping.
// So in this case is ok to transform to another kind
throw new IllegalStateException( nsae );
} catch ( NoSuchPaddingException nspe ) {
// What can you do when there is no such padding ( whatever that means ) ??
// I guess not much, in either case you won't be able to encrypt the given string
throw new IllegalStateException( nsae );
}
// line 109 won't say it needs a return anymore.
}
try {
// risky code ...
} catch( Exception e ) {
// a bomb has just exploited
// you should NOT ignore it
}
// The code continues here, but what should it do???