System.out::println 两个冒号什么意思

System.out::println双冒号解析
System.out::println 中的双冒号 :: 是 Java 8 引入的 方法引用(Method Reference) 运算符。

#方法引用是什么?
方法引用是一种简化 Lambda 表达式的语法糖,用于直接指向已经存在的方法。

等价关系:
java
// Lambda 表达式
x -> System.out.println(x)

// 方法引用(等价写法)
System.out::println
两者功能完全相同,但方法引用更加简洁。

#方法引用的四种类型
1. 静态方法引用 - Class::staticMethod
java
// Lambda 表达式
Function<String, Integer> parser1 = s -> Integer.parseInt(s);

// 方法引用
Function<String, Integer> parser2 = Integer::parseInt;

// 使用
System.out.println(parser2.apply("123")); // 输出: 123
2. 实例方法引用 - instance::instanceMethod
java
// Lambda 表达式
Consumer<String> printer1 = s -> System.out.println(s);

// 方法引用(System.out 是一个实例)
Consumer<String> printer2 = System.out::println;

// 使用
printer2.accept("Hello World"); // 输出: Hello World
3. 特定类型的任意对象的实例方法 - Class::instanceMethod
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// Lambda 表达式
names.sort((s1, s2) -> s1.compareTo(s2));

// 方法引用
names.sort(String::compareTo);

// 另一种常见用法
List<String> upperNames = names.stream()
    .map(String::toUpperCase)  // 等价于 s -> s.toUpperCase()
    .collect(Collectors.toList());
4. 构造方法引用 - Class::new
java
// Lambda 表达式
Supplier<List<String>> supplier1 = () -> new ArrayList<>();

// 方法引用
Supplier<List<String>> supplier2 = ArrayList::new;

// 使用
List<String> list = supplier2.get();
#深入理解 System.out::println
语法解析:
System.out:PrintStream 类的实例
println:PrintStream 类的实例方法
System.out::println:引用 System.out 对象的 println 方法

实际应用场景:
java
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange");

// 传统 for 循环
for (String fruit : fruits) {
    System.out.println(fruit);
}

// 使用 Stream + 方法引用(推荐)
fruits.stream()
      .forEach(System.out::println);

// 等价于:
fruits.stream()
      .forEach(fruit -> System.out.println(fruit));
#方法引用 vs Lambda 表达式
何时使用方法引用:
java
// ? 推荐使用方法引用(更简洁)
list.forEach(System.out::println);
list.stream().map(String::toUpperCase);

// ? 不必要的 Lambda(冗长)
list.forEach(x -> System.out.println(x));
list.stream().map(s -> s.toUpperCase());
何时使用 Lambda 表达式:
java
// ? 需要复杂逻辑时使用 Lambda
list.stream()
    .filter(s -> s != null && !s.isEmpty())  // 方法引用无法表达复杂条件
    .map(s -> "Item: " + s.toUpperCase())     // 需要字符串拼接
    .forEach(System.out::println);
#更多实用示例
在 Stream API 中的应用:
java
List<String> names = Arrays.asList("john", "jane", "bob", null, "");

// 链式方法引用
List<String> result = names.stream()
    .filter(Objects::nonNull)           // 静态方法引用
    .filter(String::isEmpty).negate()   // 实例方法引用
    .map(String::toUpperCase)           // 实例方法引用
    .sorted(String::compareToIgnoreCase)// 实例方法引用
    .collect(Collectors.toList());

result.forEach(System.out::println);
#自定义方法引用:
java
class StringUtils {
    // 自定义静态方法
    public static boolean isPalindrome(String s) {
        if (s == null) return false;
        return new StringBuilder(s).reverse().toString().equals(s);
    }
}

// 使用方法引用
List<String> words = Arrays.asList("radar", "hello", "level", "world");
List<String> palindromes = words.stream()
    .filter(StringUtils::isPalindrome)  // 自定义静态方法引用
    .collect(Collectors.toList());

palindromes.forEach(System.out::println); // 输出: radar, level
#性能考虑
方法引用和 Lambda 表达式在性能上没有显著差异,因为:
两者都会在运行时生成类似的字节码
JVM 会对热点代码进行即时编译优化
选择依据应该是代码的可读性而非性能

可读性对比:
java
// ? 更易读
users.stream()
     .map(User::getName)
     .filter(name -> name != null && name.length() > 0)
     .forEach(System.out::println);

// ? 较难理解
users.stream()
     .map(user -> user.getName())
     .filter(name -> name != null && name.length() > 0)
     .forEach(name -> System.out.println(name));
#总结
语法	|类型	|等价 Lambda
System.out::println	实例方法引用	|x -> System.out.println(x)
String::toUpperCase	特定类型方法引用|s -> s.toUpperCase()
Integer::parseInt	静态方法引用	|s -> Integer.parseInt(s)
ArrayList::new	构造方法引用		|() -> new ArrayList<>()
核心要点:

:: 是方法引用运算符

System.out::println 是对 println 方法的引用
方法引用让代码更简洁、更易读
在简单场景下替代 Lambda 表达式
广泛用于 Stream API 和函数式编程
方法引用是现代 Java 编程中的重要特性,熟练掌握能让你的代码更加优雅和函数式!

下午7:18:05: 正在执行 ':StudentManagementSystem.main()'… > Task :compileJava > Task :processResources UP-TO-DATE > Task :classes > Task :StudentManagementSystem.main() java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=gbk at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:706) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229) at StudentManagementSystem.initDatabase(StudentManagementSystem.java:39) at StudentManagementSystem.<init>(StudentManagementSystem.java:24) at StudentManagementSystem$5.run(StudentManagementSystem.java:299) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "java.sql.Connection.createStatement()" because "this.conn" is null at StudentManagementSystem.loadStudentData(StudentManagementSystem.java:267) at StudentManagementSystem.<init>(StudentManagementSystem.java:30) at StudentManagementSystem$5.run(StudentManagementSystem.java:299) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
06-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值