从其地址获取对象

时间:2018-05-09 05:38:28

标签: java oop pointers memory reference

这只是一般知识,我很确定它可能不可能,但我很想知道。

假设我有一个Student类对象s1,我将它传递给myFunc(s1.toString())函数。我没有超越toString()功能。当参数到达函数时,我可以仅通过它的地址引用回原始对象吗?

代码:

public static void main(){
    Student s1;
    myFunc(s1.toString());
}
public static myFunc(String address){
    Student s2;
    s2 = //get s1 object from address string
}

3 个答案:

答案 0 :(得分:5)

虽然常见实现中的默认哈希码确实使用对象地址来生成它,但它不可逆(并且使用的地址是实现细节,而不是指定的功能)。

即使有可能,对象的地址也可以在运行时更改(而默认的哈希码不会),所以即使有一种方法可以反转,它也不是一种可行的方法它

答案 1 :(得分:5)

在Java语言中,您要求做的是 by design 。与像C这样简单地将内存区域的任意控制交给程序的语言相比,JVM使用功能模型,其中安全性和某些正确性度量取决于引用可以不是伪造的(由用户定义的数据制造,例如字符串而不是由VM本身生成) - 获取对象引用的唯一官方方法是通过{创建该对象{1}}或复制现有参考资料。

答案 2 :(得分:2)

最简单的方法是在创建Student时注册所有实例:

class Student {
  private static final Map<String, Student> registry = new HashMap<>();

  Student() {
    registry.put(this.toString(), this);
  }

  static Student fromString(String address) {
    return registry.get(address);
  }
}

然后,您可以使用Student.fromString(address)获取方法中的实例。

但是有很多理由不这样做:

  • 它会泄漏内存,因为Student实例永远不会被GC,因为它们可以通过注册表访问。
  • 它不安全地发布实例
  • 这意味着您无法在构造函数之后更改toString()的值,是否要在以后提供自定义实现
  • 这是一个可变的全球状态,这绝不是一个好主意
  • 由于前一点,很难测试
  • 散列码不是唯一的,因此Student的多个实例可能具有相同的toString;在这种情况下,这里的实现将返回具有给定字符串的最后创建的实例。

作为一些让你入门。

简而言之,这样做是不明智的。

有一些方法可以实现一个注册表,避免出现部分或全部这些问题,但它会重新发挥作用。

您不需要通过字符串引用实例:使用引用引用它们。