Hm.Первое замечание: это ПЛОХО, что нужно делать в производственном коде.Я сделал это в тестах (для переключения драйвера JDBC), но это не очень хорошая идея.Но: это, вероятно, выполнимо, если вы делаете это достаточно рано.JavaC (если вы используете Oracle) не оптимизирует, все это делает JIT.Итак, если вы измените его до того, как JIT сделает свое волшебство, тогда все будет хорошо.Теоретически, вы должны иметь возможность изменять значение и после оптимизации во время выполнения, поскольку код JIT: ed должен быть помечен как недействительный после того, как вы изменили строку, но здесь я действительно катаюсь по очень тонкому льду.
Это (части) моего тестового кода.
Мне нужно изменить драйвер в этом классе:
class MysqlConnection {
private static final String DRIVER_NAME = "com.mysql.jdbc.Driver";
protected Connection instantiateNewConnection() {
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName(DRIVER_NAME).newInstance();
} catch (Exception ex) {
// handle the error
LOG.info("Class Exception: " + ex);
}
}
}
И я делаю это так:
class DBOperation {
static {
Field f = MysqlConnection.class.getDeclaredField("DRIVER_NAME");
f.setAccessible(true);
f.set(f, LocalFlipper.HSQLDB_DRIVER);
}
}
Это работает.Можно изменить окончательные поля в Java, но это не очень хорошая идея.Сначала я изменяю рассматриваемое поле, затем создаю экземпляр экземпляра, и поле DRIVET_NAME содержит драйвер jdbc, который я хочу.
Кажется, есть некоторые сомнения относительно того, будет ли это работать или нет, но я могу заверить вас в этомдействительно, попробуйте это для себя.
@ LouisWasserman: Я ушел и javap: ed части кода:
Class.forName(DRIVER_NAME).newInstance();
соответствует
28: ldc #16; //String com.mysql.jdbc.Driver
30: invokestatic #17; //Method java/lang/Class.forName(Ljava/lang/String;)Ljava/lang/Class;
33: invokevirtual #18; //Method java/lang/Class.newInstance:()Ljava/lang/Object;
Как видите, строка являетсяне встроенныйКроме того, как вы встраиваете объект (или сложный тип)?Вы можете вставить ссылку (естественно).Я согласен, что если у нас есть код, такой как
Class.forName("com.mysql.jdbc.Driver");
, то у нас нет способа получить доступ к этой строке, поскольку мы не можем получить ссылку на нее.