如何在不使用 String/toString 的情况下获取对象而不是地址?
How do I get object and not address without using String/ toString?
我需要在不使用默认字符串 class/vector API 的情况下创建自己的名为 MyString
的 String
class。我必须处理一些必需的方法,并且它们的 return 类型是预先确定的。只要不使用 String
,我可以添加其他方法。
预期用途为:
(at main) System.out.println(str.toLowerCase())
- returns 小写的 str
当我想使用 return 类型 MyString
的 toLowerCase()
方法时,我不能 return 对象内容,只能 return地址。
通常情况下,这个问题需要修改toString()
,但是由于这个方法默认需要return类型的String,所以我不能使用修改toString()
来赋值.
作业应该不那么难,不需要复杂的扩展。我的构造函数可能是问题所在,但我无法指定是哪一部分。
代码
public class MyString {
private char value[];
MyString(char[] arr){
this.value = Arrays.copyOf(arr, arr.length);
}
...
MyString toLowerCase() { // can't change return type
for (int i =0; i<value.length; i++) {
if ((int)value[i] > 64 && (int)value[i] < 91) {
value[i] = (char) (value[i]+32);
}
}
return this; // this returns address, and I can't override toString
}
System.out.println(str.toLowerCase())
的问题是它最终会调用 PrintStream.println(Object o)
,但该方法在内部有时会调用 o.toString()
,它使用从 Object#toString()
继承的代码(因为您不能'按预期覆盖 toString
作为结果 String
,这在你的项目中是被禁止的)导致形式 TypeInfo@hexHashCode
。
这意味着您不能使用 System.out.println(MyString)
。
BUT PrintStream
(实例由 System.out
持有)允许我们提供数据以不同的形式打印。在这种情况下,您可以使用 println(char[])
。您需要做的就是添加到 MyString
方法,例如 toCharArray()
,这将 return(最好是副本)由 MyString
class 保存的字符数组。
这样您就可以像 System.out.println(myStringInstance.toCharArray())
那样使用它,因此您的 main
方法中的代码需要看起来像
System.out.println(str.toLowerCase().toCharArray());
// ^^^^^^^^^^^--this should return char[]
首先,String
class 是不可变类型,即 String
的方法不会改变内部状态(即 char
数组),而是他们 return 类型 String
的新实例。
要反映该行为,您可以实施如下操作:
public MyString toLowerCase() {
char temp = new char[value.length];
// [...] Your code performing the actual logic on temp
return new MyString(temp);
}
String
class 的不变性(及其含义)在实践中非常重要。例如,以下代码产生了预期的结果:
String word = "Word";
System.out.println("I can produce upper case (" + word.toUpperCase() + ") " +
"and lower case (" + word.toLowerCase() + ") " +
"without any side-effects on the original (" + word + ").");
但是,不可能(没有“hacky”解决方案)实现这样的方法:
void shortenString(String inputAndOutput);
其次,赋值要求 class/method 必须按如下方式使用:
System.out.println(str.toLowerCase());
属性 out
实际上是一个 PrintStream
,它提供(除其他方法外)以下两个:
println(Object x)
- Prints an Object and then terminate the line.
println(String x)
- Prints a String and then terminate the line.
如果使用 Object
参数调用该方法,则内部实现会在给定对象上调用 toString()
,因此满足要求的唯一方法是覆盖此方法。不幸的是,作业不允许这样做。
但是,如果没有明确说明解决方案必须使用 java.lang.System
,您可以简单地实现自己的 System
class,它接受 MyString
,例如:
public class System {
public static class MyPrintStream /* optional: extends PrintStream */ {
public void println(MyString x) {
java.lang.System.out.println(x.getCharArray());
}
}
public static final out = new MyPrintStream();
}
这将允许您完全按照作业中的描述使用它:
import my.package.System;
public class Main {
public static void main(String[] args) {
// [...] Instantiate str
System.out.println(str.toLowerCase());
}
}
我需要在不使用默认字符串 class/vector API 的情况下创建自己的名为 MyString
的 String
class。我必须处理一些必需的方法,并且它们的 return 类型是预先确定的。只要不使用 String
,我可以添加其他方法。
预期用途为:
(at main) System.out.println(str.toLowerCase())
- returns 小写的 str
当我想使用 return 类型 MyString
的 toLowerCase()
方法时,我不能 return 对象内容,只能 return地址。
通常情况下,这个问题需要修改toString()
,但是由于这个方法默认需要return类型的String,所以我不能使用修改toString()
来赋值.
作业应该不那么难,不需要复杂的扩展。我的构造函数可能是问题所在,但我无法指定是哪一部分。
代码
public class MyString {
private char value[];
MyString(char[] arr){
this.value = Arrays.copyOf(arr, arr.length);
}
...
MyString toLowerCase() { // can't change return type
for (int i =0; i<value.length; i++) {
if ((int)value[i] > 64 && (int)value[i] < 91) {
value[i] = (char) (value[i]+32);
}
}
return this; // this returns address, and I can't override toString
}
System.out.println(str.toLowerCase())
的问题是它最终会调用 PrintStream.println(Object o)
,但该方法在内部有时会调用 o.toString()
,它使用从 Object#toString()
继承的代码(因为您不能'按预期覆盖 toString
作为结果 String
,这在你的项目中是被禁止的)导致形式 TypeInfo@hexHashCode
。
这意味着您不能使用 System.out.println(MyString)
。
BUT PrintStream
(实例由 System.out
持有)允许我们提供数据以不同的形式打印。在这种情况下,您可以使用 println(char[])
。您需要做的就是添加到 MyString
方法,例如 toCharArray()
,这将 return(最好是副本)由 MyString
class 保存的字符数组。
这样您就可以像 System.out.println(myStringInstance.toCharArray())
那样使用它,因此您的 main
方法中的代码需要看起来像
System.out.println(str.toLowerCase().toCharArray());
// ^^^^^^^^^^^--this should return char[]
首先,String
class 是不可变类型,即 String
的方法不会改变内部状态(即 char
数组),而是他们 return 类型 String
的新实例。
要反映该行为,您可以实施如下操作:
public MyString toLowerCase() {
char temp = new char[value.length];
// [...] Your code performing the actual logic on temp
return new MyString(temp);
}
String
class 的不变性(及其含义)在实践中非常重要。例如,以下代码产生了预期的结果:
String word = "Word";
System.out.println("I can produce upper case (" + word.toUpperCase() + ") " +
"and lower case (" + word.toLowerCase() + ") " +
"without any side-effects on the original (" + word + ").");
但是,不可能(没有“hacky”解决方案)实现这样的方法:
void shortenString(String inputAndOutput);
其次,赋值要求 class/method 必须按如下方式使用:
System.out.println(str.toLowerCase());
属性 out
实际上是一个 PrintStream
,它提供(除其他方法外)以下两个:
println(Object x)
- Prints an Object and then terminate the line.
println(String x)
- Prints a String and then terminate the line.
如果使用 Object
参数调用该方法,则内部实现会在给定对象上调用 toString()
,因此满足要求的唯一方法是覆盖此方法。不幸的是,作业不允许这样做。
但是,如果没有明确说明解决方案必须使用 java.lang.System
,您可以简单地实现自己的 System
class,它接受 MyString
,例如:
public class System {
public static class MyPrintStream /* optional: extends PrintStream */ {
public void println(MyString x) {
java.lang.System.out.println(x.getCharArray());
}
}
public static final out = new MyPrintStream();
}
这将允许您完全按照作业中的描述使用它:
import my.package.System;
public class Main {
public static void main(String[] args) {
// [...] Instantiate str
System.out.println(str.toLowerCase());
}
}