Java中Claims接口方法引用适配Function函数式接口的疑问
关于JWT中Claims::getSubject方法引用的疑问解答
你的测试代码
import java.util.ArrayList; import java.util.function.Function; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import app.com.javainuse.config.JwtTokenUtil; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; public class Test { public static void main(String[] args) { User u=new User("javainuse", "$2a$10$slYQmyNdGzTn7ZLBXBChFOC9f6kFjAqPhccnP6DxlWXx2lPk1C3G6",new ArrayList<>()); UserDetails ud=u; JwtTokenUtil jwtTokenUtil=new JwtTokenUtil(); String token = jwtTokenUtil.generateToken(ud); Test t=new Test(); System.out.println(t.getClaimFromToken(token, Claims::getSubject)); } public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) { final Claims claims = getAllClaimsFromToken(token); System.out.println(claims.toString()); return claimsResolver.apply(claims); } private Claims getAllClaimsFromToken(String token) { return Jwts.parser().setSigningKey("javainuse").parseClaimsJws(token).getBody(); } }
疑问解答
你困惑的核心是把「接口的方法定义」和「实际对象的方法实现」搞混了,拆解来看:
你拿到的Claims对象是有具体实现的
getAllClaimsFromToken方法里,Jwts.parser().parseClaimsJws(token).getBody()返回的不是Claims接口的空实例,而是JJWT库内部已经实现好的Claims实现类(比如DefaultClaims)的对象。这个对象已经把JWT解析后的所有claim数据都封装好了,自然包含getSubject()的具体实现逻辑。Claims::getSubject方法引用的作用
它本质上等价于Lambda表达式(Claims claims) -> claims.getSubject(),只是写法更简洁。它并没有直接调用方法,而是告诉getClaimFromToken:等你拿到真正的Claims实例后,就调用这个实例的getSubject()方法。函数式接口对方法引用的要求
函数式接口只要求方法引用的签名和接口的抽象方法签名匹配。Function<Claims, T>的抽象方法是apply(Claims t),返回泛型T;而Claims.getSubject()的签名是String getSubject(),刚好符合「输入Claims对象,输出String」的匹配规则,所以可以作为方法引用传递。这里不需要接口本身有方法实现,因为实际执行时用的是具体实例的实现。
内容的提问来源于stack exchange,提问作者user1887464
相关产品推荐
相关产品推荐

