如题,例如Class MyClass
{
   String name;
  
  public void setName(String s)
  { 
     this.name=s;
  }  public String getName()
  {
    return this.s;
  }}public class TMain
{   public static void main(String args[])
   {
      MyClass myclass=new MyClass();
      myclass.setName("Terry");
      System.out.println("hashcode:"+myclass.hashcode());
      MyClass myclass1=getClassFromHashCode(myclass.hascode()); //通过hashcode重新得到这个对象
      System.out.println("name:"+myclass1.getName());//这里应该显示出Terry
    
   }   public static Object getClassFromHashCode(int hascode)
  {
      //就是这个方法不知怎么写
  }}能解决的,我加分再结贴。谢谢

解决方案 »

  1.   

    class XObject{
        private final static Map<Integer,XObject> map=Collections.synchronizedMap(new HashMap<Integer,XObject>());
        public static XObject getObjectByRawHashCode(Integer hashCode){
            return map.get(hashCode);
        }
        XObject(){
            map.put(System.identityHashCode(this),this);
        }
    }
    class MyClass extends XObject
    {
       String name;
      
      public void setName(String s)
      { 
         this.name=s;
      }  public String getName()
      {
        return this.name;
      }}
    main: MyClass myclass=new MyClass();
            myclass.setName("Terry");
            System.out.println("hashcode:"+myclass.hashCode());
            MyClass myclass1=(MyClass) XObject.getObjectByRawHashCode(myclass.hashCode()); //通过hashcode重新得到这个对象
            System.out.println("name:"+myclass1.getName());//这里应该显示出Terry
      

  2.   

    TO hbwhwang: J2EE方面的开放经验绝对比你这个开班授课的江湖游医要丰富. 想做老师, 就多回答问题,不会回答别混分.把等级搞上去了才有说服力.
      

  3.   

    treeroot(旗鲁特) ( ) 
    你的这个方法是要预先定义好才能得到的,如果里面数据有变化,那么hashcode肯定会变化,这个时候你又取不出来了
    所以,应该不能用你的那种方法来从 hashcode取出对象
      

  4.   

    terry_yip(搞了几年开发,现在才来恶补基础,请别见笑!):没想到那句“汗,狂汗”伤害了你的自尊~
    抱歉了,兄弟!
    =======
    你的问题在JAVA DOC中有答案,Object类的hashCode()方法里面有这个方法的详细说明。
    我英文不好,就不给你翻译了,你自己看看吧。
      

  5.   

    谢谢treeroot的详尽代码,不过以那种原理来看,应该要改Object类的代码,才能使所有的对象都能通过hashcode取到吧?
      

  6.   

    TO hbwhwang:从你说推荐我看Java Doc中的Object类的hashCode方法,我就觉得你都没看清我的这个问题问什么,这个问题是问从hashcode取得Object的问题,而不是问hashcode用来做什么的,如果是google一下或查看JDK文档就找到答案的,我也不会发贴问.你有可能是说hashcode不是唯一的这个问题, 这个可能性我考虑过,得到了Object后,用getClass()方法就可以知道是不是我想要的Object了. 总之,用"你真的搞了多年的开发吗??汗!狂汗!"来回答一个你没看清楚的问题,是"针对人而不是针对技术问题 ", 有点不合适的,是吧?
      
      

  7.   

    terry_yip(搞了几年开发,现在才来恶补基础,请别见笑!) :
    你错了,我看清楚了你的问题才说那句话的。你题目中的类MyClass没有继承,那么就是继承自JAVA的Object。因此你所说的hashCode就是Object的hashCode。
    关于Object的hashCode,在JAVA DOC中,有这段话:
         * As much as is reasonably practical, the hashCode method defined by 
         * class <tt>Object</tt> does return distinct integers for distinct 
         * objects. (This is typically implemented by converting the internal 
         * address of the object into an integer, but this implementation 
         * technique is not required by the 
         * Java<font size="-2"><sup>TM</sup></font> programming language.)
    也就是说:Object的hashCode,(一般)是根据对象的内部地址(internal address)转化(计算)而来的。
    从理论上(我说的是理论上,而实际上除非你非常深入了解JVM),如果我们如果找到了这个内部地址,那么我们还是有办法取回对象的。可是这个算法可能(我是说可能,我也没看过源码)是不可逆的,也就是说,你不一定能通过hashCode反算出internal address。当然现在唯一的一条路就显示出来了:
    1、java的hashCode算法必须可逆
    2、有办法把变量myclass1刷成你得到的internal address=============
    我说的“汗,狂汗”没有别的意思,也不是为了捞分!(没见过接分的这么说话的吧)
    我只是感叹于你写的“搞了几年开发”
    我个人认为“搞了几年开发”的技术人员不可能不知道上面的内容。
      

  8.   

    我还是觉得从hashcode转化成对象不太可能
      

  9.   

    解决方案还是有的吧,例如添加一个实时map,记录hashcode和对象引用
    直接似乎是不行的
      

  10.   

    TO hbwhwang:你说对了,搞了几年开发的人,不可道不知道上面内容,我六年前就知道Object类是所有类的超类,所有的对象中都默认继承Object类的方法. 我不知道我说过的内容中,你从哪里看出来我是不知道上面这个知识点的.你的JavaDoc的内容,在Eclipse上,随便Ctrl+点击"Object"这个单词都可以看到,至于hashCode()是一个native方法,我也知道,但不代表native方法中实现的东西,就不能提取出来,万一sun另外做了另一个native方法,可以让你提取,而我们平时少用不知道呢? 又或者sun没有提供,但有人可以通过别的算法实现呢? 我就是因为有这个猜测所以才发贴问.        就像前面treeroot所说的,他讲的也是一个解决办法,不过他要继承一个自定义的类,如果要把JVM中所有的类都找得到,就得改变所有类的超类----Object类的源代码,上面我都讲过了这个问题了,证明我是很清楚Object是所有类的超类这个知识点的.我很谢谢他的回贴,虽然不是最好的,但起码他是提供了一个可行的解决方法.我可以这样讲,通过hashcode返过来找到hashcode对应对象,是可以实现的,Spring中已经有相似的这个功能, 我没空研究它的源码,所以才想请教一下大家.
      

  11.   

    了解,算了不吵了,如果我言语不慎伤害了你,再次跟你说声抱歉~既然你认可treeroot(旗鲁特) 的办法,那我也可以给你一种办法,不用继承,但是得用工厂。
    public MyClassFactory{
        static Map<Integer,MyClass> map=new HashMap<Integer,MyClass>(); 
        private MyClassFactory(){}
        public synchronized static MyClass getInstance(){
              MyClass m=new MyClass();
              map.put(m.hashCode(),m);
              return m;
        }
        public synchronized static Object getClassFromHashCode(int hascode){
            return map.get(new Integer(hashCode)); 
        }
    }在你每次需要MyClass对象的时候,不要new,而是这样:
    MyClass myclass=MyClassFactory.getInstance();
    然后你就可以:
    MyClass myclass2=MyClassFactory.getClassFromHashCode(myclass.hashCode());
      

  12.   

    OK,我的言论也有点过激,我也say sorry.在这里,其实我说明一下我的设想,我们做项目做多了,就会发现,很多时候,出现的错误都是很隐蔽的,有时客户对你说:"我好像先按这里,再按那里,然后输入什么什么,再进去, 就报错了",但你到现场时,却怎么也发现不了错误,你要客户方的人再模拟一次,好像又没错,这个问题真的很烦,最后我们最终解决问题时发现,多数都是对象中的某些变量值不规范造成的,程序员的水平也有高有低,同一个人的精神状态也有好有差,你不可能要求程序一做出来,就有足够的健壮性去处理各种不规范的变量值的,所以我就设想出这样一种模式来处理-----当JVM抛出不能处理的Exception时, 马上得到抛出Exception的对象, 并把这个对象用ObjectOutPutStream记录在文本或者数据库中, 于是, 我们通过log4j的报错时间,就可以定位到记录这个错误对象的媒介,并把它还原, 从而就跟踪到这个对象里面的所有变量的值, 那么查起错来就容易多了.    我之所以问本贴的这个问题,其实就是发现Exception中,可以得到抛出错误的对象的hashcode, (用Thowable里面的getStackTrace()得到StackTraceElement,然后调用StackTraceElement.hashcode()得到抛出错误的对象的hashcode),然后我就想把Exception的构造方法改一下,进一步通过hashcode来得到发生错误的对象,然后再把这个对象持久化了,当然,这个对象要实现Serialisable接口, 这就是我的想法. TreeRoot的方法可以实现,但需要再把Object类的代码改一下.hbwhwang的方法其实和treeroot的原理是一样的,都是先把对象和hashcode存在一个静态的Map里面, 只不过换成了工厂模式.   我两个月前已经发贴问过这个问题,结果用Plain Java的API得不到实现方法, 后来用Spring的ExceptionInterceptor来实现了, 但是我不满足于功能的实现,我还想知道实现的原理.  
      

  13.   

    如果用Map来分别存放hashcode ,Object的这种方法,是可行,但会有一个问题,随着系统的运行,Map中的Object越来越多,而不释放,这就有危险了。
      

  14.   

    起始修改java.lang.Object源码是行的通的,但是绝对不推荐
    只要自己写一个java.lang.Object.java,重新定义一些方法,要么重新打包rt.jar里面
    要么启动的时候放到bootclasspath前面,这样引导类加载器就会加载你实现的Object,
    儿忽略掉rt.jar中的Object(不过这个参数不是标准参数)
    java -Xboolclasspath/p myobject.jar 
      

  15.   

    haha, 大师们都跑这开会来啦?兄弟搬个板凳来学习学习  ^_^楼主提出这个问题的初衷实在让兄弟感到钦佩,难能可贵!如果楼主能在一开始就把背景交待一下就更好了。现在经常看到一些帖子,上来就问一个看似比较离奇的问题,等纠缠到最后发现他遇到的问题根本就不应该用他想的思路去解决。我当然不是说本帖,只是说如果一开始就交待清楚的话,能避免不少误会。楼主说的“项目中纠错”的问题,的确是个问题。以前我没想到还可以用这种手段处理,以后得多想想了  *_*
      

  16.   

    maquan('ma:kju) :别太当回事~~
    你去研究一下,就不会滔滔江水了~~
      

  17.   

    使用AspectJ,例:public interface HashCode
    {
      public int hashCode();
    }@Aspect
    public class HashCodeImpl implements HashCode
    {  public int hashCode()
      {
         //...在这里将对象和它的hasCode值进行缓存
      }  @DeclareParents ( value = "foo.MyClass1" , defaultImpl = HashCodeImpl.class )
      //这时的foo.MyClass是需要通过hasCode来获取原对象的类
      private HashCode h1 ;  //如果有多个类需要处理,如下添加
      @DeclareParents ( value = "foo.MyClass2" , defaultImpl = HashCodeImpl.class )
      private HashCode h2 ;  ....}
    使用AspectJ编译(可以是jar或java文件)后就可以只对需要的类进行这样的处理,
    此方法对原代码没有任何改变
      

  18.   

    AspectJ编译后的字节码实际上给所有经过处理的类加上了接口HashCode,接口的方法实现是HashCodeImpl中的实现
      

  19.   

    原来AspactJ是这样用的,谢谢flyxxxx让我们长了见识~~!!!^-^TO treeroot:你说“要么启动的时候放到bootclasspath前面,这样引导类加载器就会加载你实现的Object,”能不能具体讲一下,怎么把myobject.jar 启动的时候放到bootclasspath前面?你的那句命令不能运行,我在google粗略地找了一下,也没有相关的资料。谢谢了。贴子再加10分。
      

  20.   

    http://blog.csdn.net/treeroot/archive/2006/07/22/960778.aspx