英文:
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 < 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,]+");
if (name.length != 3) {
throw new ArrayIndexOutOfBoundsException();
}
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;
}
}
答案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("[\\s,]+");
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("[\\s,]+");
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("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;
}
}
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("[\\s,]+");
System.arraycopy(rawElements, 0, names, 0, rawElements.length);
output:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at stackoverflow.OutOfBound.main(OutOfBound.java:8)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论