为什么在Java中返回类实例内的类实例?

时间:2015-11-04 17:28:25

标签: java spring class oop

我来自JavaScript和Node.js背景,虽然我有大多数OOP基础知识,但有许多我不太了解的Java基础知识。例如,我正在做a Spring tutorial并且马上发现了一些困扰我的语法。

第一个演练是一个hello world应用程序。首先,我们设置了一个Greeting类:

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

首先,我不明白为什么他们在类本身中定义类的实例。为什么不直接向公共类添加参数?无论如何,这不是我的问题。当我们制作一个问候控制器时,我迷失的地方是:

package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    // This ensures that HTTP requests to /greeting are mapped to the greeting() method.
    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
            String.format(template, name));
    }
}

在这个文件中,我得到public Greeting greeting创建一个Greeting类的新实例,但是当构造函数有两个long idString content时,它只有一个参数。接下来,它们返回该类的另一个实例,这次使用与构造函数结构匹配的参数。

为什么会这样?

4 个答案:

答案 0 :(得分:2)

何时使用链接

在带有自动完成功能的IDE较为常见的语言中,功能序列通常很常见。例如,大多数Visual C#开发人员都使用Visual Studio。因此,如果您使用C#开发,则向该行的用户添加方法可以节省该行的时间,因为Visual Studio将帮助您创建字符串。

另一方面,您将看到诸如PHP之类的语言具有很强的动态性,并且在IDE中通常不具有自动完成功能。仅当使用正确的phpDocs公开顺序方法时,该顺序才适用。

什么是链接?

给一个名为Foo的类,以下两个方法都是可链接的。

function what() { return this; }
function when() { return new Foo(this); }

一个是对当前实例的引用,而一个创建了一个新实例这一事实并不能改变它们是顺序方法的事实。

没有黄金规则规定顺序方法应仅引用当前对象。连续和连续的道路可以跨越两个不同的类别。例如,

class B { function When() { return true; } };
class A { function What() { return new B(); } };

var a = new A();
var x = a.What().When();

在以上任何示例中都没有对此进行引用。代码是a.What()。当()是序列的示例时。有趣的是,B类从未分配给变量。

当返回值用作表达式的更高版本时,该方法受到限制。

还有更多示例

//从未分配返回值。

 myFile.Open("something.txt").Write("stuff").Close();

//表达式中使用了两条链

int x = a.X().Y() * b.X().Y();

//创建新字符串的链

string name = str.Substring(1,10).Trim().ToUpperCase();

何时使用this和new(this)

大多数语言中的字符串不可更改。顺序方法调用总是创建新的字符串。可以修改诸如StringBuilder之类的对象的地方。

一致性是最佳做法。

如果您有修改对象状态并返回状态的方法,请不要混淆返回新实例的方法。而是创建一个名为Clone()的特定方法,该方法将明确执行此操作。

 var x  = a.Foo().Boo().Clone().Foo();

这对于内部发生的事情更加明显。 走出去并欺骗

我将此步骤称为后一步,因为它解决了序列化的许多常见问题。这基本上意味着您从原来的班级毕业到新的临时班级,然后返回原来的学期。

除了为原始类别提供特殊功能外,没有任何临时类别,只有在特殊情况下。

很多时候该系列需要改变情况,但是A类不能代表所有这些潜在情况。因此,在字符串中,将向A提供一个包含引用的新类。这使程序员可以输入状态并返回到A。

在这里是理想的,让特殊状态知道b。

class A {
    function Foo() { return this; }
    function Boo() { return this; }
    function Change() return new B(this); }
}

class B {
    var _a;
    function (A) { _a = A; }
    function What() { return this; }
    function When() { return this; }
    function End() { return _a; }
}

    var a = new A();
    a.Foo().Change().What().When().End().Boo();

现在这是一个非常简单的示例。如果您想拥有更多控制权,则B可以返回具有不同方法的A的新超类型。

我也建议您也是黑客社区,以获取最佳的Java教程:https://hackr.io/tutorials/learn-java

答案 1 :(得分:0)

我不知道我是否理解你的问题,但我试着给你一个答案。

Normaly你使用Controller(在你的情况下是GreetengsController)向世界公开资源。此资源是Greeting对象/实例。用两个参数初始化对象(在你的情况下是一个long和一个String)。

public Greeting greeting(... String name) 

是一个方法(函数)声明,它说:这个fuctionn期望一个String“name”作为参数并返回一个对象Greeting到客户端(调用者),并带有

return new Greeting(....)

返回Greeting对象。通常情况下,您可以使用对象进行更多操作(不仅返回新实例)

我不知道我是否回答了你的问题。如果不。请告诉我。

答案 2 :(得分:0)

首先,我建议您学习Java编程语言,不使用Spring:

使用

public class Greeting {

您正在定义一个名为Greeting的课程。那是你的班级。

在这门课程中你有:

public Greeting(long id, String content) {

这是该类的构造函数。在Java中,没有调用其构造函数的对象。因此,为了创建一个新对象,你必须调用它的构造函数。

然后你有

public class GreetingController {

这定义了另一个类,在本例中为GreetingController。

这个类有一个方法(函数):

 public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name)

此方法接收名为name的字符串,并返回Greeting的对象(实例)。为了返回Greeting的实例,你必须先创建实例,然后调用它的构造函数:

return new Greeting(counter.incrementAndGet(),
            String.format(template, name));

这一行调用构造函数并传递两个参数,与之前在Greeting类的构造函数中定义的参数相同。

答案 3 :(得分:-1)

公开问候语问候语(@RequestParam(值="名称",defaultValue ="世界")字符串名称)仅定义方法问候语,返回类型问候语

new Greeting(counter.incrementAndGet(),
        String.format(template, name))

上面的代码实际上创建了一个新的Greeting实例并将其返回。