如何在Java中实现Ruby Blocks的等效功能?
Ruby blocks let you wrap custom code around a predefined method's logic—like the myf method that prints "start" and "end" around whatever code you pass in. In Java, we don't have native blocks, but since Java 8, we can use functional interfaces and lambda expressions to achieve exactly the same behavior.
Here's how to replicate your Ruby example in Java:
Step 1: Define the Method with a Functional Interface Parameter
We'll use Java's built-in Consumer<Integer> functional interface, which represents an operation that takes a single integer input and returns no result (perfect for matching your Ruby block's behavior):
import java.util.function.Consumer; public class BlockExample { public static void myf(int i, Consumer<Integer> block) { System.out.println("start"); // Invoke the passed-in "block" code with the integer i block.accept(i); System.out.println("end"); } public static void main(String[] args) { // Call myf with different lambda expressions (our "blocks") myf(3, (i) -> System.out.println(i * 10)); myf(4, (i) -> System.out.println(i - 10)); } }
Step 2: Run the Code
When you execute this, the output will be identical to your Ruby example:
start 30 end start -6 end
How It Works
- Functional Interface:
Consumer<Integer>acts as the "contract" for our block—it tells Java that we expect a function that takes anIntegerand returns nothing. - Lambda Expression: The code
(i) -> System.out.println(i * 10)is our Java equivalent of the Ruby block{ |i| puts i * 10 }. It's an anonymous function that gets passed tomyf. - Invoking the Block: Inside
myf, we callblock.accept(i)to run the lambda code, just like Ruby'syield i.
Custom Functional Interfaces (If Needed)
If your block needed to return a value or take multiple parameters, you could define your own functional interface instead of using the built-in ones. For example, if your block returned an integer:
@FunctionalInterface interface MyBlock { int execute(int i); } public static void myfWithReturn(int i, MyBlock block) { System.out.println("start"); int result = block.execute(i); System.out.println(result); System.out.println("end"); } // Call it like this: myfWithReturn(5, (i) -> i * 2); // Outputs start, 10, end
This approach gives you the same flexibility as Ruby blocks, letting you pass custom logic into methods to wrap around predefined code.
内容的提问来源于stack exchange,提问作者Sida Zhou

