Nu är det ganska många år sedan jag senaste knackade Java-kod professionellt och har skrivit minimalt med Java frivilligt, så min bild av "bra Java" kanske inte är helt aktuellt.
Kikade lite på Pi4J. Tror att från ett rent Java-perspektiv gör man saker ungefär som förväntat. Problemet är att huvudmålet med all kod är i slutändan att den ska lösa en uppgift och sättet Pi4J "löser" uppgiften är allt annat än optimal givet att vad man normalt vill få ut av den här typen av bibliotek.
Några axplock på problem
I botten använder man wiringPi, ett C bibliotek som primärt är tänkt för att ge folk från Arduino-världen något som ser ungefär lika ut på en RPi. Problemet här är: Arduino är tänkt för mikrokontrollers som sitter i en tight loop och gör något extremt specifikt, RPi snurrar på en multi-user OS där man inte vill köra busy-wait. Pi4J "löser" detta med att skapa trådpooler. Rätt sätt: låt Linux-kärnan polla HW m.h.a. interrupt (vilket med rätt val av GPIO-bibliotek är fullt möjligt då Linux-kärnan stödjer detta)
Man har så många abstraktionslager som jag har lite svårt att se vad de tillför just då man bygger allt på ett abstraktionslager (wiringPi) som hanterar de mesta av skillnaderna i HW. Enda som egentligen skiljer är smådetaljer i pinout (och även det lär skilja rätt lite då de flesta kort man stödjer är RPi kompatibla).
Ignorerar man ovan så är ändå en av huvudfunktionerna i ett GPIO bibliotek att ge effektiv och låglatens access till HW-pinnarna, att då blanda in flera OS-trådar i ett icke realtids-OS är en rejäl anti-pattern (och att ovanpå det köra en miljö med tracing-GC gör inte saken bättre, men det är ett litet problem i detta fall)
Sedan är vissa abstraktioner lite märkliga, ser inte riktigt vad GpioPinPwm tillför när man också har GpioPinPwmOutput. Inte så att PWM på något sätt är vettigt för input och även GpioPinPwmOutput är inte interface (man skiljer på HW PWM och software PWM, vilket är vettigt).
Interface GpioPinDigitalOutput har allt för mycket. Varför finns det blink() och pulse() metoder? De är väl ändå en service som kan utföras på en digital utgående pinne, inte en del av vad en digital pinne är?
Pi4J är mer ett ramverk än ett bibliotek, vilket för vad man försöker lösa känns rätt onödigt. Känns också som det mer är ett projekt för författaren av koden för att denne ska få testa på så många olika Java och RPi finesser som möjligt än ett vettig bibliotek för andra att använda... Exempel på en bra abstraktion av GPIO är t.ex. denna (långt mindre API jämfört med Pi4J även om tittar enbart på GPIO, ändå får det in långt fler användbara koncept som HW-interrupt utan trådar och läsa/skiva grupper av pinnar atomärt).
Angående OOP. Finns absolut användningsområden för OOP, men det är bara en teknik bland många och få saker inom programmering lär användas på fel ställe som OOP... Om man inte har nytta av tillstånd så är OOP fel val, så är extremt osannolikt att t.ex. affärslogik passar bra till OOP då själva logiken brukar vara helt tillståndslös. Samma sak gäller moderna "mikroservices" med REST APIer. Finns självklart undantag, det finns alltid.
OOP är ofta en väldigt dålig idé i multitrådade program. Detta då effektiv och korrekt synkronisering av data kräver att man explicit ser hur data representeras, vilket en av hörnsterna i OOP förhindrar (Rust är en av få språk som fått detta riktigt rätt, data och beteende är helt separerat där och språket garanterar att data endera är read-only eller bara kan nås från en enda tråd).
https://miro.medium.com/max/2114/1*8BSPw3u9qBdqJxrEfrN9JA.png
Ofta är det bara två av ovan man vill ha, polymorfism och abstraktion. Men dessa har i sig inget med OOP att göra, går hur bra som helst att använda båda de koncepten helt fristående från OOP.
Att allt måste finnas i kontext av en klass är en kraftig designmiss i Java. Hindrar inte att man använder icke-OOP teknik, men det ser lite yxigt ut ibland. Sedan finns ju andra språk som fungerar ihop med Java-plattformen, som Kotlin, vilket visar att problemet inte alls är fundamentalt i Java (i alla fall inte i plattformen Java).