如何在不使用 String/toString 的情况下获取对象而不是地址?

How do I get object and not address without using String/ toString?

我需要在不使用默认字符串 class/vector API 的情况下创建自己的名为 MyStringString class。我必须处理一些必需的方法,并且它们的 return 类型是预先确定的。只要不使用 String ,我可以添加其他方法。

预期用途为:

(at main) System.out.println(str.toLowerCase()) - returns 小写的 str

当我想使用 return 类型 MyStringtoLowerCase() 方法时,我不能 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);
}

Stringclass 的不变性(及其含义)在实践中非常重要。例如,以下代码产生了预期的结果:

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());
    }
}