java 中的String是不可被继承的,怎么样可以变相的去继承他呢?
例如:要生成一个新的类TT,这个类中要定义的方法除了String类中的所有方法外,还有一个额外的方法,就是因为String是不能被继承的,所以要把String的所有的方法都手动的写到TT这个类中,有没有什么其他的办法可以完成呢,也就是说怎么做可以达到继承String的目的

解决方案 »

  1.   

    修改src裡面的String.java。
      

  2.   

    String 实现了  Serializable, Comparable<String>, CharSequence  这三个接口
    TT类可以也实现这些接口,可以根据自己的需求来实现每个接口中的方法
      

  3.   

     = = 。。final类不可被继承是铁律。。应该不能被打破的。。所以采用聚合是比较好的答案吧
       
              public class Test { private String str ;

    public Test(String str){
    this.str =str;
    }
        
        public void suiYi(){}

    public static void main(String[] args) {
              new Test("").str.equals(null);
              new Test("").str.suiYi();
    }
    }这样既可以使用String的方法就是调用的时候麻烦了一步。。又可以使用自己的方法
      

  4.   

    这不能叫变相继承,众所周知,当B类继承了A类之后,可以这样声明:A a = new B();
    LZ所描述的“变相继承”根本达不到这个目的
      

  5.   

    运用代理的思想class TString{
     
     private  String s;
     
     public TString(String s){
     this.s=s;
     }
     
     private  boolean equal(String s){
     //运用代理的形式调用String的方法,所有方法均可以这样
     return s.equals(s);
     }
     
     
    //自定义方法
     private  void userMethod(){
     ///
     }
     
     public static void main(String[] args){
     TString s = new TString("str");
     s.equals("2");//String的方法
     s.userMethod();//自定义方法
     }
     }
      

  6.   

    连继承的基本功能都没了,还叫什么继承能String s = new TString("str");么?
      

  7.   

    变相继承,那要看你怎么理解了。
    如果仅仅是需要String所有的方法,并且可以扩展,那把源码抄来试试
    否则的话,好像真没办法了
      

  8.   

    修改 final 类是非常危险的事情,但也不是完全没有办法。如果一定要这么做的话,在 Sun 的编译器和 JVM 实现中可以这样做(使用引导类路径选项):1,找到 java.lang.String 的源代码,修改成你所需要的代码,就把这个类编译打包成 jar 文件(比如叫做 string.jar),这个类编译后应该有两个 .class 文件;
    2,使用 javac -Xbootclasspath/p:string.jar Test.java 进行编译;
    3,使用 java -Xbootclasspath/p:string.jar Test 运行。这样的话,整个 java.lang.String 就被你替换掉了。PS:如果 string.jar 不在当前路径下时,需要使用完整的路径,如带有空格需要使用双引号引起来。
      

  9.   


    这面试官的水平可想而知了,要重写 String 类,还要比 String 类更优秀,这种人在国内应该不存在。
      

  10.   

    如果使用静态代理,那不靠谱而动态代理只能对接口类进行代理,String可不是个接口,所以我个人认为使用代理,还没有使用楼上几位说的使用组合靠谱
      

  11.   

    你不可能去实现 String 的功能,光一个“+”(字符串连接运算符)你就做不到!
      

  12.   


    Cglib 底层使用了 ASM 字节码工具,可以实现无接口的代理,不过你得知道的是代理类是原来类的子类,因此说 final 类是不能创建动态/静态代理对象的。
      

  13.   

    建议你参照String类的源码 按照其实现的接口等 实现你自己的 myString 类然后 你看着办吧。PS:你能保证你的类在任何条件和环境下工作正常吗?
      

  14.   

    +1String的地位不是其他普通类能比的。除了手工替换class以外,其他方法都不能100%实现String的功能
      

  15.   


    其他倒还有办法搞但操作符重载,JAVA做不到, 得c++
      

  16.   

    官方发布的 rt.jar 是带有数字签名的,而且这个 jar 是 sealed,也就是说 java.lang 里面的所有东西必须和 rt.jar 在同一个 jar 文件内,如果改了 java.lang.String 的源码的话,就得把 rt.jar 重新打包才能工作,否则 jvm 会报告错误拒绝加载 String 类,因为它不符合 seal 规定。但是,如果我们重新打包 rt.jar 就违背了 SUN 的 JRE 的 license 并且也算是安全风险,因为你不再有 rt.jar 的数字签名了。当然自已在自己的项目中用用不发布到外面也没关系。
      

  17.   

    重写String类不可行,String类中好多方法是通过java native方法实现的,这也决定了没有人可以比java api做的更好,当然不排除例外
      

  18.   

    “变相继承”,肯定面试官的意思就是非继承方法了。要不就是改java实现了。
      

  19.   

    用动态代理拦截charAt,永远返回第二个字符:
    package silenceburn;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    class StringAddProxy implements InvocationHandler{
    String realString;

    public StringAddProxy(String s){this.realString = s;}

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    // TODO Auto-generated method stub
    args[0]=1;
    return method.invoke(realString, args);
    }

    }
    public class StringProxy {

    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s = new String("HELLO"); CharSequence s1 = (CharSequence)s;
    System.out.println("current str first :" + s1.charAt(0));

    CharSequence   ps = (CharSequence)Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), new StringAddProxy(s));
    System.out.println("after proxy str first :" + ps.charAt(0));
    System.out.println("after proxy str first :" + ps.charAt(2));
    System.out.println("after proxy str first :" + ps.charAt(3));
    System.out.println("after proxy str first :" + ps.charAt(4));


    }}必须用String在JDK中实现的接口CharSequence来操作,
    否则如LS很多兄弟讲的那样,由于String的特殊性质,代理无从谈起。
      

  20.   

    如果说这是一道面试题,那你直接告诉面试官:你有病啊,你懂不懂java啊!
      

  21.   


    呵呵,试一下我在 15 楼的方法中的 Xbootclasspath 这个引导类路径参数就知道了虽然 Xbootclasspath/p 参数官方的注释是:Note: Applications that use this option for the purpose of overriding a class in rt.jar should not be deployed as doing so would contravene the Java 2 Runtime Environment binary code license.但这并不是表示不能使用。
      

  22.   

    改一个试试吧:把 String.java 拿出来,放到一个新建的 java/lang 的目录中,把其中的 toString() 方法改为:[code=Jav]    /**
         * This object (which is already a string!) is itself returned.
         *
         * @return  the string itself.
         */
        public String toString() {
            System.out.println("----------");
            return this;
        }[/code]加了个输出。编译该文件:javac -d . java\lang\String.java
    打包:jar cvf string.jar java\lang\*.class写个 Test.java:[code=Jav]public class Test {    public static void main(String[] args) {
            String str = "hello, java boot classpath";
            System.out.println(str.toString());
        }
    }[/code][code=Jav]F:\temp\jre>ls -all
    total 1
    drwxrwxrwx   1 user     group           0 Feb 19 11:37 .
    drwxrwxrwx   1 user     group           0 Feb 19 11:30 ..
    -rw-rw-rw-   1 user     group         174 Feb 19 11:31 Test.java
    drwxrwxrwx   1 user     group           0 Feb 19 11:27 javaF:\temp\jre>javac -d . java\lang\String.javaF:\temp\jre>jar cvf string.jar java\lang\*.class
    标明清单(manifest)
    增加:java/lang/String$1.class(读入= 189) (写出= 145)(压缩了 23%)
    增加:java/lang/String$CaseInsensitiveComparator.class(读入= 1184) (写出= 701)(压缩了 40%)
    增加:java/lang/String.class(读入= 17422) (写出= 8500)(压缩了 51%)F:\temp\jre>javac -Xbootclasspath/p:string.jar Test.javaF:\temp\jre>java -Xbootclasspath/p:string.jar Test
    ----------
    hello, java boot classpathF:\temp\jre>[/code]