Чи існує поняття вбудованих функцій у java, або його замінено чимось іншим? Якщо є, як він використовується? Я чув це public
, static
і final
методи - це вбудовані функції. Чи можемо ми створити власну вбудовану функцію?
Чи існує поняття вбудованих функцій у java, або його замінено чимось іншим? Якщо є, як він використовується? Я чув це public
, static
і final
методи - це вбудовані функції. Чи можемо ми створити власну вбудовану функцію?
Відповіді:
У Java оптимізація зазвичай проводиться на рівні JVM. Під час виконання, JVM проводить деякий "складний" аналіз, щоб визначити, які методи вбудувати. Він може бути агресивним у вбудованому виконанні, і JVM Hotspot насправді може вбудувати не завершальні методи.
Компілятори Java майже ніколи не вбудовують будь-який виклик методу (JVM робить все це під час виконання). Вони роблять вбудовані постійні часу (наприклад, кінцеві статичні примітивні значення). Але не методами.
Для отримання додаткових ресурсів:
Стаття: Двигун продуктивності Java HotSpot: Приклад вкладки методу
Вікі: Вбудований у OpenJDK , не повністю заповнений, але містить посилання на корисні дискусії.
Ні, в Java немає вбудованої функції . Так, ви можете використовувати загальнодоступний статичний метод в будь-якому місці коду, коли розміщується в загальнодоступному класі. Компілятор java може робити вбудоване розширення статичним або кінцевим методом, але це не гарантується.
Зазвичай такі оптимізації коду здійснюються компілятором у поєднанні з JVM / JIT / HotSpot для сегментів коду, які використовуються дуже часто. Також в Java не відомі інші концепції оптимізації, такі як оголошення регістру параметрів.
Оптимізацію не можна примусити оголосити в java, але зробити компілятором та JIT. У багатьох інших мовах ці декларації часто є лише підказками компілятора (ви можете оголосити більше параметрів реєстру, ніж процесор, решта ігнорується).
Оголошення методів Java статичним, остаточним або приватним також є підказками для компілятора. Ви повинні використовувати його, але ніяких гарантій. Продуктивність Java динамічна, а не статична. Перший виклик до системи завжди повільний через завантаження класу. Наступні дзвінки проходять швидше, але залежно від пам’яті та часу виконання, найпоширеніші дзвінки оптимізовані за допомогою запущеної системи, тому сервер може стати швидшим під час виконання!
final
не впливайте на вбудований JIT
Java не пропонує способу вручну підказати, що метод повинен бути накреслений. Як зазначає @notnoop у коментарях, вбудовування, як правило, виконується JVM під час виконання.
jdk.internal.vm.annotation.ForceInline
Те, що ви сказали вище, є правильним. Іноді остаточні методи створюються як вбудовані, але іншого способу явного створення вбудованої функції в java немає.
final
навіть не має ніякої різниці щодо того, введений метод чи ні.
Приклад із реального життя:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
Тоді в інших класах я можу вийти, якщо код закінчився. Якщо я посилаюсь на змінну EXPIRED_ON з іншого класу, константа вводиться в байт-код, що робить його дуже важким для відстеження всіх місць у коді, який перевіряє термін придатності. Однак якщо інші класи викликають метод isExpired (), викликується власне метод, тобто хакер може замінити метод isExpired іншим, який завжди повертає помилковим.
Я погоджуюсь, було б дуже примусити компілятора надати статичний остаточний метод всім класам, на які він посилається. У цьому випадку вам навіть не потрібно включати клас Control, оскільки він би не знадобився під час виконання.
З мого дослідження, цього неможливо зробити. Можливо, деякі інструменти Obfuscator можуть це зробити, або ви можете змінити процес збирання для редагування джерел перед компіляцією.
Що стосується доведення, якщо метод із класу управління розміщено в рядку до іншого класу під час компіляції, спробуйте запустити інший клас без класу Control на classpath.
Що ж, існують методи, які можна назвати "вбудованими" методами у java, але залежно від jvm. Після компіляції, якщо машинний код методу менше 35 байт, він буде негайно переведений в метод вбудованого, якщо машинний код методу менше 325 байт, він може бути переведений у вбудований метод, залежно від jvm.
так що, здається, немає, але ви можете використовувати це вирішення, використовуючи guava або еквівалентну реалізацію класу функцій, оскільки цей клас надзвичайно простий, напр .:
assert false : new com.google.common.base.Function<Void,String>(){
@Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
так, це мертвий код лише для того, щоб пояснити, як створити складний блок коду (в межах {}), щоб зробити щось настільки специфічне, що не повинно заважати нам створювати для нього будь-який метод, AKA inline!