Como detectar se String.substring copia os dados de caractere

Eu sei que para o Oracle Java 1.7 atualização 6 e mais recente, ao usarString.substring, a matriz de caracteres internos da String é copiada e, para versões mais antigas, é compartilhada. Mas eu não encontrei nenhuma API oficial que me dissesse o comportamento atual.

Caso de uso

Meu caso de uso é: em um analisador, gosto de detectar seString.substring copia ou compartilha o array de caracteres subjacente. O problema é que, se a matriz de caracteres é compartilhada, então meu analisador precisa explicitamente "não compartilhar" usandonew String(s) para evitar problemas de memória. No entanto, seString.substring de qualquer maneira copia os dados, então isso não é necessário, e copiar explicitamente os dados no analisador pode ser evitado. Caso de uso:

// possibly the query is very very large
String query = "select * from test ...";
// the identifier is used outside of the parser
String identifier = query.substring(14, 18);

// avoid if possible for speed,
// but needed if identifier internally 
// references the large query char array
identifier = new String(identifier);
O que eu preciso

Basicamente, eu gostaria de ter um método estáticoboolean isSubstringCopyingForSure() que detectaria senew String(..) Não é necessário. Eu estou bem se a detecção não funcionar se houverSecurityManager. Basicamente, a detecção deve ser conservadora (para evitar problemas de memória, prefiro usarnew String(..) mesmo que não seja necessário).

Opções

Eu tenho algumas opções, mas não tenho certeza se elas são confiáveis, especialmente para JVMs não-Oracle:

Verificando o campo String.offset

/**
 * @return true if substring is copying, false if not or if it is not clear
 */
static boolean isSubstringCopyingForSure() {
    if (System.getSecurityManager() != null) {
        // we can not reliably check it
        return false;
    }
    try {
        for (Field f : String.class.getDeclaredFields()) {
            if ("offset".equals(f.getName())) {
                return false;
            }
        }
        return true;
    } catch (Exception e) {
        // weird, we do have a security manager?
    }
    return false;
}

Verificando a versão da JVM

static boolean isSubstringCopyingForSure() {
    // but what about non-Oracle JREs?
    return System.getProperty("java.vendor").startsWith("Oracle") &&
           System.getProperty("java.version").compareTo("1.7.0_45") >= 0;
}

Verificando o comportamento Existem duas opções, ambas são bastante complicadas. Uma é criar uma string usando charset customizado, depois criar uma nova string b usando substring, depoismodificar a string original e verifique se b também é alterado. A segunda opção é criar uma cadeia enorme, depois algumas substrings e verificar o uso da memória.

questionAnswers(4)

yourAnswerToTheQuestion