Spring Boot 在java中如何在构造函数参数中使用new关键字?

nx7onnlm  于 2023-04-20  发布在  Spring
关注(0)|答案(2)|浏览(161)

我正在学习Spring Security,遇到了这个类:

org.springframework.security.core.userdetails.User$UserBuilder

我对两件事感到困惑:
1.$符号的用途是什么,它只是一种命名约定,还是它在功能上表示什么?
1.在同一个类中,有一个这样的构造函数:
User$UserBuilder(new org.springframework.security.core.userdetails.User(){} x0) { }
这里我们使用new关键字作为参数。它是什么意思?
我试着在网上搜索它,但没有运气

t98cgbkg

t98cgbkg1#

你正在看反编译的代码并试图学习。
那是个非常糟糕的主意;反编译器维护得不是很好,结果会产生一些奇怪的结构,通常是非法的(比如这个-它不能编译)。如果你知道关于java类文件格式的细节,你可以弄清楚,但是,这是...学习起来相当复杂,而且很少有用,所以,作为一个新手甚至是一个中级程序员,你不应该学习的东西。
给出:

package com.foo;

class Bar {
  class Baz {
    public Baz() {}
  }
}

当你编译它的时候,它变成了2个类文件,因为在类文件级别,内部类根本不是一个东西. javac通过生成大量的糖来使它看起来像它们存在。它归结为有2个单独的类:

package com.foo;

class Bar {
}

package com.foo;

class Bar$Baz {
  private final Bar this$Bar;
  public Bar$Baz(Bar this$Bar) {
    this.this$Bar = this$Bar;
  }
}

毕竟,从一个非静态的内部类,你可以从你的外部类引用示例方法。你必须在某些东西上调用这些方法,所以你需要一个包含类的示例,这就是this$Bar字段的作用。
你现在看到的,是一个蹩脚的反编译器反编译的结果:

new User().new User.UserBuilder();

这是一个有效的java,但很少使用-它正在构造一个新的非静态内部类(User.UserBuilder),并显式沿着应该作为其容器的外部类(User)的示例。通常,您将在User中的一些非静态上下文中调用new UserBuilder(),它相当于this.new UserBuilder()
spring是开源的,因此,你的方法没有什么意义。只要..检查源代码:source of User.java
注意,UserBuilder类实际上是static,所以很明显反编译器彻底搞混了。由于它是静态的,没有“外部的示例”可供引用,因此不需要非常奇怪的instanceOfOuter.new Inner()语法,但反编译器显然认为发生了这种情况(UserBuilder没有接受User对象的构造函数;不在Java代码中,也不在类文件中)。

6tr1vspr

6tr1vspr2#

可能是你在看反编译的代码或其他东西(为什么spring安全团队中的任何人都会使用一个名为x0的参数)我相信你指的是User class source code
美元符号基本上意味着类UserDetails定义在类User中(源文件中的第326行)通常,美元字符是Java中命名某些东西的有效符号(例如,可以命名变量a$b,但Java编译器使用它来显示一个类定义在另一个类下。

相关问题