Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
扩展java.lang.String_Java_String_Inheritance - Fatal编程技术网

扩展java.lang.String

扩展java.lang.String,java,string,inheritance,Java,String,Inheritance,String被声明为final,但是是否有合法或其他机制可以扩展它并替换equals(String other)方法 不,绝对不是。如果需要某种“其他”类型的字符串,请创建另一种可能包含字符串的类型: public final class OtherString { private final String underlyingString; public OtherString(String underlyingString) { this.underlyin

String被声明为final,但是是否有合法或其他机制可以扩展它并替换equals(String other)方法

不,绝对不是。如果需要某种“其他”类型的字符串,请创建另一种可能包含字符串的类型:

public final class OtherString {
    private final String underlyingString;

    public OtherString(String underlyingString) {
        this.underlyingString = underlyingString;
    }        

    // Override equals however you want here
}

不能扩展标记为final的类。您可以使用合成将字符串对象放入其中,也可以手动滚动您自己的版本。这可以通过字符数组和其他创建字符串类的魔法来实现

我想最接近的方法就是创建一些实现的类。大多数JDK字符串操作方法都接受CharSequence。例如结合toString()、String和valueOf()的各种方法的良好实现,您可以非常接近自然替代品。

直接继承String类是不可能的,因为它是最终的。还有包装类java.lang.Integer、java.lang.Float等。。。都是最终的。

现在,有办法了。使用它可以扩展每个Java类。以下是字符串的示例:

package extensions.java.lang.String;

import manifold.ext.api.*;

@Extension
public class MyStringExtension {

  public static void print(@This String thiz) {
    System.out.println(thiz);
  }

  @Extension
  public static String lineSeparator() {
    return System.lineSeparator();
  }
}
可按如下方式使用:

String name = "Manifold";
name.print();
String.lineSeparator();
另一个例子可以在这里找到:


注意,这个流形仍然是alpha

我编写了一个简单的Strings类,它模仿java.lang.String并可以扩展。这只是为了证明String背后的核心实现需求并不“神秘”或“复杂”。而且,您可以使用它来创建密码扩展和更有效地管理字符串

需要:

  • 本机呼叫big endian。(请参见专用静态本机布尔值。) isBigEndian();)
  • 其他字符串方法
package com.paintedintel.util;
导入java.nio.charset.StandardCharset;
/**
* 
*@作者大卫·厄里
*@date 2/8/2020
* 
*Strings是基于StringUTF16的轻量级字符串实现。
*它的唯一目的是创建一个可以扩展字符串的系统
*这样一来,绳子的类型就可以在不增加携带重量的情况下延伸
*额外的对象引用。
* 
*字符串扩展之所以重要,有两个原因:
*1)额外对象引用使代码速度降低50%
*10倍的速度提升仅为5倍。作为观察/比较的对象,以及
*否则,管理字符串是昂贵的。
*2)理解字符串的类型对代码理解有很大的好处
*您正在使用(名称、值、字段、InitValue、注释…)。常数
*例如,在观察时,列表的评估会大大简化
*改为列出。
*    
*通过使用类型、域、基准、,
*StreamDomain、StreamCase和其他对象作为复杂对象。
*/
公共类字符串{
最终字节[]值;
/**缓存字符串的哈希代码*/
private int hash;//默认值为0
受保护字符串(字符串值){
if(值!=null){
this.value=value.getBytes();
this.hash=value.hashCode();
}否则{
this.value=新字节[0];
this.hash=0;
}
}
字符串(字节[]值){
这个值=值;
this.hash=Strings.hashCode(值);
}
@凌驾
公共字符串toString(){
返回新字符串(值,StandardCharsets.UTF_8);
}
公共字符串str(){
返回到字符串();
}
公共布尔等于(字符串str){
返回(str==null)?((value==null | | this.length()==0)?true:false):str.hashCode()==value.hashCode();
}
公共布尔等式(字符串str){
返回等于(str);
}
字节[]获取字节(){
返回值;
}
int getHash(){
返回散列;
}
公共整数长度(){
返回值.length>>1;
}
/**
*这是基于StringUTF16的
*@param值
*@返回
*/
同步的公共静态int哈希代码(字节[]值){
int h=0;
int length=value.length>>1;
for(int i=0;i=0&&index索引你希望用这个实现什么?我不久前也在想同样的问题,我得到的唯一答案是将一个字符串包装到另一个类,然后使用这个另一个类幸运的是,final类是SCJP书籍中的final类:
如果程序员可以自由扩展String类,那么文明——正如我们所知——可能会崩溃。
但是有很好的理由想要扩展String。很多东西都是带有额外限制/条件的字符串。您的密码是字符串,但并不是每个字符串都适合您密码(合法字符等)。我认为Scala允许你对字符串进行子类型划分?SCJP的书很烂。要么给我们一个真正的理由,要么就不提它。我有很多扩展字符串的用例……或者至少能够创建一个
MyClass
,然后能够执行
MyClass='MyString'
。还有一些语言允许你重写我想说的是,我不喜欢C++ C++字符串处理(AUTIORACE),但它不像是文明因为它而崩溃了。但是字符串S =“HI”;是可行的,但不是其他字符串s =“嗨”;“Enfestto:当然。你必须写代码<其他字符串S=新的其他字符串(HI))。;
我有一个问题..如果实现这个,可能会有内存问题?@marlonpya:恐怕这个问题太模糊了,无法回答。@marlonpya:不比您创建的任何其他类多或少。这个答案只包括标准继承-替换equals方法的替代方法如何?这是一个非常好的评论…p很可能是OP问题的最佳解决方案。真的很有趣!
    package com.paintedintel.util;
    
    import java.nio.charset.StandardCharsets;
    
/**
 * 
 * @author David Urry
 * @date 2/8/2020
 * 
 * Strings is a light weight string implementation based on StringUTF16.
 * It's sole purpose is to create a system where strings can be extended
 * so that the type of string can be extended without the weight of carrying
 * extra object references.  
 * 
 * Strings extension is important for 2 reasons:
 * 1) The extra object reference slows the code down by a factor of 50% making 
 *    a 10X speed improvement only 5X.  As the object of looking at/comparing and
 *    otherwise managing strings is expensive.
 * 2) The code understanding benefits greatly from understanding the type of string
 *    you are working with (Name, Value, Field, InitValue, Comment...).  The constant
 *    evaluation of List<String> for example is greatly simplified when observing
 *    List<Field> instead.
 *    
 * This problem was also greatly simplified by working with Type, Domain, Datum,
 * StreamDomain, StreamCase and other objects as complex objects.
 */

public class Strings {
  final byte[] value;
    /** Cache the hash code for the string */
    private int hash; // Default to 0
 
  protected Strings(String value){
      if (value != null) {
          this.value = value.getBytes();
          this.hash = value.hashCode();
      } else {
          this.value = new byte[0];
          this.hash = 0;
      }
  }
  
  Strings(byte[] value){
      this.value = value;
      this.hash = Strings.hashCode(value);
  }
  
  @Override
  public String toString() {
      return new String(value, StandardCharsets.UTF_8);
  }
  
  public String str() {
      return toString();
  }
  
  public boolean equals(String str) {
      return (str == null)?((value == null || this.length() == 0)?true:false):str.hashCode() == value.hashCode();
  }
  
  public boolean eq(String str) {
      return equals(str);
  }
  
  byte[] getBytes() {
      return value;
  }
  
  int getHash() {
      return hash;
  }
  
  public int length() {
      return value.length >> 1;
  }
  
  /**
   * this is based on StringUTF16 
   * @param value
   * @return
   */
  synchronized public static int hashCode(byte[] value) {
        int h = 0;
        int length = value.length >> 1;
        for (int i = 0; i < length; i++) {
            h = 31 * h + getChar(value, i);
        }
        return h;
    }
    
    // intrinsic performs no bounds checks
  synchronized static char getChar(byte[] val, int index) {
        assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
        index <<= 1;
        return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                      ((val[index]   & 0xff) << LO_BYTE_SHIFT));
    }

    //private static native boolean isBigEndian();

//    private static boolean isBigEndian() {
//        //as of 2018 there are no major BigEndian systems left.
//        // This is because it's less processing to convert & work with
//        // Little-Endian.
//        return false;
//    }
    
    static final int HI_BYTE_SHIFT = 0;
    static final int LO_BYTE_SHIFT = 8;
//    static {
//        if (isBigEndian()) {
//            HI_BYTE_SHIFT = 8;
//            LO_BYTE_SHIFT = 0;
//        } else {
//            HI_BYTE_SHIFT = 0;
//            LO_BYTE_SHIFT = 8;
//        }
//    }
    
    synchronized public static int length(byte[] value) {
        return value.length >> 1;
    }
}