当前位置:  开发笔记 > 编程语言 > 正文

当我尝试编译Java代码时,为什么会出现"Exception;必须被捕获或声明被抛出"?

如何解决《当我尝试编译Java代码时,为什么会出现"Exception;必须被捕获或声明被抛出"?》经验,为你挑选了3个好方法。

考虑:

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

我得到一个未报告的例外:

java.lang.Exception; must be caught or declared to be thrown
byte[] encrypted = encrypt(concatURL);

以及:

.java:109: missing return statement

我该如何解决这些问题?



1> victor hugo..:

你所有的问题都源于此

byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;

其中包含在try,catch块中,问题是如果程序发现异常,则不返回任何内容.像这样(将其修改为程序逻辑):

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){
        return null;            // Always must return something
    }
}

对于第二个,您必须从加密方法调用中捕获异常,如下所示(也可以将其修改为程序逻辑):

public void actionPerformed(ActionEvent e)
  .
  .
  .
    try {
        byte[] encrypted = encrypt(concatURL);
        String encryptedString = bytesToHex(encrypted);
        content.removeAll();
        content.add(new JLabel("Concatenated User Input -->" + concatURL));

        content.add(encryptedTextField);
    setContentPane(content);
    } catch (Exception exc) {
        // TODO: handle exception
    }
}

你必须从中吸取教训:

具有返回类型的方法必须始终返回该类型的对象,我的意思是在所有可能的场景中

必须始终处理所有已检查的异常


最后一个要点并不完全正确.RuntimeException是Exception的子类及其子类,是未经检查的异常,不需要被捕获或声明被抛出.

2> OscarRyz..:

问题出在这个方法中:

  public static byte[] encrypt(String toEncrypt) throws Exception{

这是方法签名,几乎说:

方法名称是什么:加密

它接收的参数是什么:名为toEncrypt的String

其访问修饰符:public static

如果它在调用时可能抛出异常.

在这种情况下,方法签名表示在调用时,此方法"可能"可能会抛出"异常"类型的异常.

    ....
    concatURL = padString(concatURL, ' ', 16);
    byte[] encrypted = encrypt(concatURL); <-- HERE!!!!!
    String encryptedString = bytesToHex(encrypted);
    content.removeAll();
    ......

因此编译器会说:要么用try/catch构造包围它,要么声明方法(正在使用的地方)自己抛出"Exception".

真正的问题是"加密"方法定义.没有方法应该返回"Exception",因为它太通用了,可能隐藏其他类型的异常更好的是有一个特定的异常.

试试这个:

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.
  }

基本上在这种特殊情况下,您应该确保加密包在系统中可用.

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???

如果代码失败,最好快速失败

以下是一些相关的答案:

捕获Java中的异常

何时选择已检查和未检查的例外

为什么不必显式声明可能会在Java中抛出一些内置的异常?

除RuntimeException之外的异常



3> Bill the Liz..:

第一个错误

java.lang.Exception的; 必须被捕获或声明被抛出byte [] encrypted = encrypt(concatURL);

表示您的encrypt方法抛出一个异常,该异常未被actionPerformed您调用它的方法处理或声明.阅读Java Exceptions Tutorial中的所有相关内容.

您可以选择几个选项来获取要编译的代码.

您可以throws Exceptionencrypt方法中删除并实际处理内部异常encrypt.

您可以从方法中删除try/catch块encrypt并将throws Exception异常处理块添加到您的actionPerformed方法中.

通常最好在最低级别处理异常,而不是将其传递到更高级别.

第二个错误只是意味着您需要将return语句添加到包含第109行的任何方法(encrypt在本例中也是如此).方法中有一个return语句,但如果抛出异常,则可能无法访问它,因此您需要返回catch块,或者删除try/catch encrypt,如前所述.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有