La riflessione in Java rende le sue funzioni "di prima classe"

6

Ho sempre sentito parlare di come Java non supporta le funzioni di prima classe, che è un vantaggio che si ottiene dai linguaggi funzionali, l'unico modo per simularlo in Java è attraverso l'uso di classi interne anonime ecc.

Tuttavia, da quello che posso vedere Java supporta le prime funzioni attraverso l'uso della sua reflection API. Ad esempio, posso creare un oggetto metodo da una classe e quindi chiamarlo su un numero di oggetti di quella classe. Mi rendo conto che non è potente come le funzioni di prima classe in altre lingue. Ad esempio in Python puoi fare quanto segue:

class Test:
    def __init__(self, num):
        self.number = num
    def add(self, num):
        self.number += num
test = Test(1)
method = test.add
method(2)

Non è possibile farlo in Java perché è necessario avere un riferimento all'oggetto su cui si desidera richiamare il metodo. Tuttavia puoi ancora trattare il metodo come un oggetto che è ciò che definisce le funzioni di prima classe. Immagino che l'oggetto metodo non sia realmente la funzione reale, ma piuttosto un oggetto meta-dati, anche se usando la riflessione può essere trattato come tale. Forse ho solo bisogno di chiarimenti su cosa definisce una funzione di prima classe.

    
posta toc777 01.04.2011 - 14:17
fonte

3 risposte

6

Una funzione di prima classe è quella in cui la funzione è disponibile da sola. C, C ++ e Ruby consentono questo approccio. Java richiede che la funzione sia legata a una classe e ne fornisce solo una rappresentazione dei metadati, anche se quella classe è semplicemente una raccolta statica di funzioni. C # supporta le funzioni di prima classe con lambdas (che si basano su lambda calcolo ) e delegati .

Ruby è una delle lingue che supporta veramente le funzioni di prima classe. La differenza è che non solo puoi definire le funzioni da solo, ma puoi passarle come argomenti e invocare metodi su di esse. Controlla l'oggetto Proc di Ruby che viene utilizzato per rappresentare un blocco arbitrario di codice.

Il risultato finale di avere funzioni di prima classe è il fatto che si presta a costrutti di codifica molto potenti e flessibili. Questo è chiaramente diverso dall'hacking attorno alle funzioni di prima classe usando l'API di reflection.

Java non ha il pieno supporto di funzioni di prima classe. L'API reflection può darti qualche parvenza di funzioni di prima classe se l'oggetto Method fa riferimento a un metodo static . In sostanza puoi invocare un metodo statico come questo:

Method reference = mathClass.getMethod("sqrt");

// NOTE: the first parameter is for the object instance,
// but for static methods it is ignored
double answer = (double)reference.invoke(null, 4);

Non appena lavori con un metodo di istanza, perdi l'abilità di funzione di prima classe. Potresti essere in grado di hackerare insieme un supporto delegato basato sulla riflessione simile a C #, ma il codice risultante sarà molto più lento. Il "delegato" si prenderà cura di mantenere il riferimento dell'oggetto per le chiamate future.

    
risposta data 01.04.2011 - 14:35
fonte
6

Le funzioni di prima classe non sono funzioni esterne alle classi, le funzioni di prima classe sono funzioni che possono essere referenziate e passate ad altre funzioni, proprio come possono essere numeri interi o oggetti. Chiamare una funzione tramite la riflessione, è vicino - ti permette di fare alla fine la stessa cosa, ma ha un livello extra di astrazione che lo rende più difficile da usare. Hai un involucro attorno alla funzione e puoi passarlo, ma non hai un riferimento diretto alla funzione.

Java 8 ha reso le funzioni di prima classe con l'introduzione dei riferimenti al metodo . Puoi avere un metodo che accetta esplicitamente una funzione come argomento, quindi chiama tale funzione all'interno del metodo, ma non hai quel * wrapper, il che rende più semplice l'utilizzo.

* Sì, lo so, in alcuni casi esiste un wrapper nascosto, ma questo è un dettaglio di implementazione, che è libero di cambiare.

    
risposta data 22.01.2018 - 00:56
fonte
-1

the only way to simulate it in Java is through the use of anonymous inner classes etc..

Questo è semplicemente sbagliato. Nulla ci impedisce di dichiarare una classe di alto livello che abbia solo il metodo (i) e di trattare le istanze di quella classe come funzioni. Se la classe non ha effettivamente uno stato, si toglie che abbiamo bisogno solo di una sua istanza, ma questo è un dettaglio tecnico.

Pertanto, direi che le funzioni di prima classe sono una funzione linguistica di cui i progettisti linguistici erano a conoscenza e che volevano supportarla esplicitamente.

    
risposta data 09.04.2011 - 19:32
fonte

Leggi altre domande sui tag