数组*不会抛出越界异常

huangapple go评论69阅读模式
英文:

Array *not throwing out of bounds exception

问题

我正在尝试学习异常处理。我似乎无法让以下代码引发数组越界异常,即当它超出3个元素时:

String[] a = names(scnr);

我知道,大多数人讨厌数组越界错误,我正在尝试让它发生,但是我怎么都找不出我做错了什么。我整天都在做这个,并且搜索了各种资料。但是我似乎找不到我正在寻找的确切内容。所以我需要一些帮助和观点。

所以我正在输入一个完整的字符串,我正在基于逗号和空格对其进行分隔(修剪和拆分),然后将这些部分存储到一个数组中(String[] name),然后传递到主函数并与 String[] a 一起输出。无论我如何操作,当我超过3个元素时,它都不会出现错误。我只是不显示 a[4] 及以后的内容。但这并不是我真正想做的。这是我第一次使用 Java 类,所以请温柔一些,哈哈。

有什么建议吗?

英文:

I'm trying to learn about exception handling. I can't seem to get
String[] a = names(scnr); To throw an out of bounds exception when it goes beyond 3 elements. I know, most people hate the out of bounds error and I'm trying to make it happen and for the life of me I cannot figure out what I'm doing wrong. Been at it all day and googled all kinds of stuff. But I cannot seem to find exactly what I'm looking for. So I could use some help and perspective.

So I'm inputting a full string that I'm delimiting (trim and splitting) based on commas and spaces and then the pieces are being stored into an array (String []name), then passed to main to be output with String[] a. So it's not erroring when I go beyond 3 elements no matter how I do it. I can just not display anything beyond a[4]. But that's not really what I'm trying to do. Its my first java class so be gentle haha.

Any suggestions?

 import java.util.*;

public class ReturnArrayExample1  
{  
	public static void main(String args[])
	{  
		Scanner scnr = new Scanner(System.in);
		String[] a = names(scnr);           
		for (int i = 0; i < 3; i++) 
		{
			System.out.println(a[i] + " in index[" + i + "].");
		}
		scnr.close();
	}  

	public static String[] names(Scanner scnr)  
	{  							
		String[] name = new String[3];		// initializing
		boolean run = true;
	do 
	{
		try
		{
		System.out.println("Enter 3 names separated by commas ',':(Example: keith, mark, mike)");
		String rawData = scnr.nextLine();
			if(rawData.isEmpty())
			{
				System.err.println("Nothing was entered!");
				throw new Exception();
			}
			else
			{
				name = rawData.trim().split("[\\s,]+");
				run = false;
			}
		}
		catch(ArrayIndexOutOfBoundsException e)
		{
			System.err.println("Input is out of bounds!\nUnsuccessful!");
		}
		catch(Exception e)
		{
			System.err.println("Invalid entry!\nUnsuccessful!");
		}
	}
	while(run == true);
	
	System.out.println("Successful!");
	scnr.close();
	return name;  
	}  
}

答案1

得分: 1

如果我理解正确您希望在`names`数组不包含*恰好* 3个元素的情况下抛出ArrayOutOfBoundsException异常以下代码与您编写的代码相同只是添加了一个if语句来实现这一点

```java
import java.util.*;

public class ReturnArrayExample1  
{  
   public static void main(String args[])
   {  
       Scanner scnr = new Scanner(System.in);
       String[] a = names(scnr);           
       for (int i = 0; i < 3; i++) 
       {
           System.out.println(a[i] + "在索引[" + i + "]。");
       }
       scnr.close();
   }  

   public static String[] names(Scanner scnr)  
   {                           
       String[] name = new String[3];      // 初始化
       boolean run = true;
       do 
       {
           try
           {
               System.out.println("输入用逗号‘,’分隔的3个名称(示例:keith,mark,mike):");
               String rawData = scnr.nextLine();
               if(rawData.isEmpty())
               {
                   System.err.println("未输入任何内容!");
                   throw new Exception();
               }
               else
               {
                   name = rawData.trim().split("[\\s,]+");
                   if (name.length != 3) {
                       throw new ArrayIndexOutOfBoundsException();
                   }
                   run = false;
               }
           }
           catch(ArrayIndexOutOfBoundsException e)
           {
               System.err.println("输入越界!\n不成功!");
           }
           catch(Exception e)
           {
               System.err.println("无效输入!\n不成功!");
           }
       }
       while(run == true);
       
       System.out.println("成功!");
       scnr.close();
       return name;  
   }  
}
英文:

If I understand you correctly, you want to throw an ArrayOutOfBoundsException if the names array does not contain exactly 3 elements. The following code is the same as the one you wrote with an if-statement to do just that.

import java.util.*;
public class ReturnArrayExample1  
{  
public static void main(String args[])
{  
Scanner scnr = new Scanner(System.in);
String[] a = names(scnr);           
for (int i = 0; i &lt; 3; i++) 
{
System.out.println(a[i] + &quot; in index[&quot; + i + &quot;].&quot;);
}
scnr.close();
}  
public static String[] names(Scanner scnr)  
{                           
String[] name = new String[3];      // initializing
boolean run = true;
do 
{
try
{
System.out.println(&quot;Enter 3 names separated by commas &#39;,&#39;:(Example: keith, mark, mike)&quot;);
String rawData = scnr.nextLine();
if(rawData.isEmpty())
{
System.err.println(&quot;Nothing was entered!&quot;);
throw new Exception();
}
else
{
name = rawData.trim().split(&quot;[\\s,]+&quot;);
if (name.length != 3) {
throw new ArrayIndexOutOfBoundsException();
}
run = false;
}
}
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println(&quot;Input is out of bounds!\nUnsuccessful!&quot;);
}
catch(Exception e)
{
System.err.println(&quot;Invalid entry!\nUnsuccessful!&quot;);
}
}
while(run == true);
System.out.println(&quot;Successful!&quot;);
scnr.close();
return name;  
}  
}

答案2

得分: 0

据我所理解,您期望在以下代码行中抛出一个异常 (ArrayIndexOutOfBoundsException):

name = rawData.trim().split("[\\s,]+");

如果数组 (name) 的大小固定为 3,而输入超过了 3,则应该抛出异常;但事实并非如此。

原因在于 Java 中赋值的方式。当您声明 String[] name = new String[3]; 时,会在 Java 堆中创建一个对象,并将其引用分配给位于堆栈内存中的变量 name
当执行这一行 name = rawData.trim().split("[\\s,]+"); 时,将在堆中创建一个新的数组对象,并且变量 name 开始指向在堆上新创建的数组对象。注意:旧对象在一段时间后会被垃圾回收。
这最终改变了数组变量 (name) 的长度,因此不会引发任何 ArrayIndexOutOfBoundsException 异常。

您可以通过在控制台上打印对象,比如在其初始化和赋值后添加 System.out.println(name);,更清楚地理解这一点。

我还建议您参考这个链接(https://books.trinket.io/thinkjava2/chapter7.html#elements),以了解如何创建、初始化和复制数组等内容。

带有系统输出命令的代码(用于理解):

import java.util.Scanner;

public class ReturnArrayExample1 {

    public static void main(String args[]) {
        Scanner scnr = new Scanner(System.in);
        String[] a = names(scnr);
        System.out.println("Variable (a) is referring to > " + a);
        for (int i = 0; i < 3; i++) {
            System.out.println(a[i] + " in index[" + i + "].");
        }
        scnr.close();
    }

    public static String[] names(Scanner scnr) {
        String[] name = new String[3]; // initializing
        System.out.println("Variable (name) is referring to > " + name);
        boolean run = true;
        do {
            try {
                System.out.println("Enter 3 names separated by commas (Example: keith, mark, mike)");
                String rawData = scnr.nextLine();
                if (rawData.isEmpty()) {
                    System.err.println("Nothing was entered!");
                    throw new Exception();
                } else {
                    name = rawData.trim().split("[\\s,]+");
                    System.out.println("Now Variable (name) is referring to > " + name);
                    run = false;
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                System.err.println("Input is out of bounds!\nUnsuccessful!");
            } catch (Exception e) {
                System.err.println("Invalid entry!\nUnsuccessful!");
            }
        } while (run == true);

        System.out.println("Successful!");
        scnr.close();
        return name;
    }
}

如果您希望在输入超过 3 时抛出异常,有很多方法可以实现。@mohamedmoselhy.com 的一个建议也是不错的。

英文:

As far as I understand, you are expecting an exception (ArrayIndexOutOfBoundsException) to the thrown at line
name = rawData.trim().split(&quot;[\\s,]+&quot;);
with an argument that the size of array (name) is fixed to 3, and when if the input is beyond 3 then the exception must be thrown; which is not the case.

The reason is in the way assignment happens in java. When you declare String[] name = new String[3];, then an object is created in java heap and its reference is assigned to variable name which is in stack memory.
And when this line name = rawData.trim().split(&quot;[\\s,]+&quot;); gets executed then a new array object is created in heap and the variable name starts pointing to the newly created array object on heap. Note: the old object will get available for garbage collection after some time.
This eventually changes the length of the array variable (name) and you do not get any ArrayIndexOutOfBoundsException.

You can understand this more clearly by printing the object on console, like System.out.println(name); after its initialisation and post its assignment.

I will also suggest you to refer this link (https://books.trinket.io/thinkjava2/chapter7.html#elements) to understand how array are created, initialised and copied etc..

Code with system.out commands (for understanding)

import java.util.Scanner;
public class ReturnArrayExample1 {
public static void main(String args[]) {
Scanner scnr = new Scanner(System.in);
String[] a = names(scnr);
System.out.println(&quot;Variable (a) is referring to &gt; &quot; + a);
for (int i = 0; i &lt; 3; i++) {
System.out.println(a[i] + &quot; in index[&quot; + i + &quot;].&quot;);
}
scnr.close();
}
public static String[] names(Scanner scnr) {
String[] name = new String[3]; // initializing
System.out.println(&quot;Variable (name) is referring to &gt; &quot; + name);
boolean run = true;
do {
try {
System.out.println(&quot;Enter 3 names separated by commas &#39;,&#39;:(Example: keith, mark, mike)&quot;);
String rawData = scnr.nextLine();
if (rawData.isEmpty()) {
System.err.println(&quot;Nothing was entered!&quot;);
throw new Exception();
} else {
name = rawData.trim().split(&quot;[\\s,]+&quot;);
System.out.println(&quot;Now Variable (name) is referring to &gt; &quot; + name);
run = false;
}
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println(&quot;Input is out of bounds!\nUnsuccessful!&quot;);
} catch (Exception e) {
System.err.println(&quot;Invalid entry!\nUnsuccessful!&quot;);
}
} while (run == true);
System.out.println(&quot;Successful!&quot;);
scnr.close();
return name;
}
}

I you want to throw exception when input is more than 3 then there are many ways to do it. One suggestion from @mohamedmoselhy.com is also decent.

答案3

得分: 0

如果您想让Java抛出ArrayIndexOutOfBoundsException异常,您需要保留已创建的names实例,并让Java将数组复制到您的names数组中:

String[] names = new String[3];
String[] rawElements = rawData.trim().split("[\\s,]+");
System.arraycopy(rawElements, 0, names, 0, rawElements.length);

输出:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at stackoverflow.OutOfBound.main(OutOfBound.java:8)
英文:

If you want java to throw an ArrayIndexOutOfBoundException you have to preserve the created names instance and let java copy the array into your names array:

    String[] names=new String[3];
String[] rawElements=rawData.trim().split(&quot;[\\s,]+&quot;);
System.arraycopy(rawElements, 0, names, 0, rawElements.length);

output:

Exception in thread &quot;main&quot; java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at stackoverflow.OutOfBound.main(OutOfBound.java:8)

huangapple
  • 本文由 发表于 2020年9月15日 13:14:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63895515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定