Wpis z mikrobloga

Pytanie do doświadczonych programistów JAVA którzy mają już za sobą niejedną rekrutację. Jak nie wyjść na totalnego idiotę kiedy to się przypadkiem dostanie pytanie, nie ważne czy na stanowisko juniora, mida czy seniora czy można zmodyfikować pole final? Bo dotarłem do rozwiązania z którego wynika że jest to możliwe a i ktoś gdzieś kiedyś o tym wspomniał i miał to pytanie na rekrutacji. Z tego co pamiętam powiedział że tak a rekruterzy nie byli zadowoleni.

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main
{
public static final Integer value = 10;

static void setFinalField(Field field, Object newValue) throws Exception
{
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}

public static void main(String args[]) throws Exception
{
System.out.println(Main.value); //before
setFinalField(Main.class.getField("value"), 20);
//Main.value = 20;
//error: cannot assign a value to final variable value
System.out.println(Main.value); //after
}
}

Testowałem to przynajmniej tu:
https://www.onlinegdb.com/online_java_compiler
albo u siebie lokalnie na JDK 1.7 bo używam starszej wersji. Nie na każdym kompilatorze do testów online to się skompiluje.

Wynik online GDB

10
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by Main (file:/home/) to field java.lang.reflect.Field.modifiers
WARNING: Please consider reporting this to the maintainers of Main
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
20

Powiedzieć im że można zmodyfikować pole final bo jest to możliwe i zaliczyć faila, bo na pytanie się odpowie nie tak jak by oczekiwali, czy też powiedzieć że nie można?

#java #programowanie #programista15k #pracait
  • 18
@daro1: nie wiem czy ty tak na serio czy jaja sobie robisz xD
refleksją to możesz zmodyfikować sobie wszystko. nie o to tu chodzi.
wspominanie o refleksji przy takim samym prostym problemie to jest red flag.
@daro1: nie ma innej możliwości niż to co napisałeś. Oczywiście takie zabawy to sztuka dla sztuki, w normalnym kodzie final jest po to, żeby było lepszy kod, bo niemutowalność ułatwia sporo rzeczy. Modyfikację pola w takim podejściu obchodzi się robiąc nową kopię obiektu
@daro1: @Saly: final nie gwarantuje niemutowalności, to nie Rust. Nie uniemożliwia też zmiany obiektu w polu final tak jak const w C++. Jedyne przed czym chroni to przed zmianą wartości samego pola ale też można, choć nie powinno się, obchodzić to refleksją. Jeśli wartość w polu to referencja na obiekt, to taki obiekt można zmieniać mimo finał chyba że jest niemutowalny.
@daro1: Dużo zależy od rekrutera. Jeśli rozmawiasz z osobą pseudo techniczną, która ma listę pytań i prawidłowych odpowiedzi to dajesz standardową odpowiedź, że po zainicjalizowaniu nie można już zmienić wartości. Jeśli natomiast rozmawiasz z kimś, kto już co najmniej kilka lat pokodował to jak najbardziej możesz wspomnieć o refleksji. Jest to narzędzie jak każde inne, to czy dobre czy złe zależy tylko i wyłączenie od sposobu i warunków użycia. Tak jak
  • 0
@63274682374: @ly000: A co jeżeli tego typu pytania są po to żeby odsiać tych którzy aplikując na dane stanowisko nie powinni wiedzieć za dużo? Bo z założenia to chyba final jest po to żeby tego nie modyfikować. Już to widzę jak jakiś junior w pracy znając refleksje czy nie wiadomo co jeszcze zmodyfikuje coś co modyfikowane być nie powinno a przez to coś nie zadziała jak powinno.
@daro1: raczej nie są po to, żeby odsiać tych, którzy wiedzą za dużo. refleksja nie powinna być pierwszą odpowiedzią przy tego typu pytaniach, bo na odpowiedź "czy można w javie zrobić X" (prawie?) zawsze można odpowiedzieć, że tak, za pomocą refleksji. dotyczy to ignorowania modyfikatorów dostępu, modyfikowania kolekcji niemutowalnych, modyfikowania zmiennych final, modyfikowania stringów, modyfikowania kodu.
owszem, juniorom zdarza się za bardzo brandzlować refleksją, wpychając ją tam, gdzie jej nie powinno
którzy aplikując na dane stanowisko nie powinni wiedzieć za dużo?


@daro1: Jeśli chcą Cię odsiać bo wiesz za dużo to tym lepiej dla Ciebie, żebyś tam nie pracował.

Jest też druga strona tego medalu. Często ludzie przeceniają swoją wiedzę tzn np. wiedzą że coś się da zrobić, ale nie mają pojęcia, że nie powinni tak robić. Dobry rekruter powinien umieć rozgraniczyć te dwie kwestie. W tym przypadku, gdybym ja zadał takie
  • 0
@eustach: A jak potem w pracy zacznie kombinować z czymś gdzie kombinować nie trzeba albo jest to nie wskazane? Bo skoro final można modyfikować w ten sposób to znaczy że jest taka realna możliwość. To po co w takim razie to final zostało wprowadzone? Bo nawet się nie skompiluje jeśli to value spróbować przypisać jakąś wartość a te warningi z GDB też są nie bez powodu. Rekruter może oczekiwać odpowiedzi tak
@daro1: Na rekrutacjach najlepiej nie odpowiadać zdawkowo tak/nie ale wytłumaczyć że można to zmienić takim sposobem. Tyczy się to też innych pytań.

Po to jest final żeby nie modyfikować i dać znać innym że mają tego nie ruszać. To że da się to zrobić jakimś hackiem (trochę za mocne słowo na użycie refleksji) to nie znaczy że tego sposobu masz używać w codziennej pracy. W 99% przypadków, nie byłoby to potrzebne
  • 0
@eustach: Dlatego moim zdaniem takie pytania mogą być podchwytliwe. Drugim takim przykładem może być pytanie jaka jest różnica między Basic Authentication a Digest Authentication i co jest bezpieczniejsze jak nie ma zainstalowanego HTTPS? I właśnie pytania w jakiej postaci mogą być przechowywane hasła (hashowane czy tylko jawnie) i w którym przypadku? Jest pewnie jeszcze wiele innych podchwytliwych pytań żeby zagiąć programistę któremu się wydaje że jest zajebisty.