Java 确保字段已从构造函数中初始化

Java 确保字段已从构造函数中初始化,java,Java,编辑:很抱歉我之前的问题,最后的关键词会让你困惑,这是不合适的。我也为我糟糕的英语感到抱歉 -----问题:------ 假设我有一个没有任何构造函数的模型类,因为我需要在许多不同的逻辑中初始化它但是我有一个notnull关键字 我需要在不同的地方使用它,但要不断检查是否所有的notnull字段都是在编译时初始化的 Model m = new Model(); m.name = "Hello"; m.age = 15; // syntax error, you should set Model.

编辑:很抱歉我之前的问题,最后的关键词会让你困惑,这是不合适的。我也为我糟糕的英语感到抱歉

-----问题:------

假设我有一个没有任何构造函数的模型类,因为我需要在许多不同的逻辑中初始化它但是我有一个notnull关键字

我需要在不同的地方使用它,但要不断检查是否所有的notnull字段都是在编译时初始化的

Model m = new Model();
m.name = "Hello";
m.age = 15;
// syntax error, you should set Model.address

我如何在java中实现这一点? Thx

假设我有一个没有任何构造函数的模型类

这是不可能的。每个类都有一个构造函数。如果不定义一个构造函数,那么最终将使用默认构造函数。就你而言:

public Model() {
    super();
}
检查是否已初始化所有最终字段

首先,必须初始化final字段,否则编译器将无法编译。因此,您必须初始化最终字段:

  • 在构造函数中
  • 在声明最终字段时
构造函数初始化

public final String name;
public final int age;

public Model() {
    this.name = "Hello";
    this.age = 13;
}
public final String name = "Hello";
public final int age = 13;

public Model() {
    super();
}
声明初始化

public final String name;
public final int age;

public Model() {
    this.name = "Hello";
    this.age = 13;
}
public final String name = "Hello";
public final int age = 13;

public Model() {
    super();
}

您应该查看生成器模式。你可以在网上找到很多关于如何使用它的文章。这是一个例子。使用构建器模式,您可以验证是否设置了某些字段,如果没有设置,则抛出异常。

如果只有final: 您可以在声明的地方实例化它们,也可以在构造函数内部实例化它们

如果最终+静态: 必须在声明的位置实例化它们

因此,由于它们不是静态的,您需要在指定它们的位置或构造函数中实例化它们。

您可以通过以下方式实现您想要的:

public class Model {
    private final String name;
    private final String address;
    private final int age;

    public Model(final String name, final String address, final int age) {
        if (name == null) {
            throw new IllegalArgumentException("please provide a name");
        }
        if (address == null) {
            throw new IllegalArgumentException("please provide an address");
        }
        this.name = name;
        this.address = address;
        this.age = age;
    }

    // getters
}
用法:

new Model("World", "Some address", 20) // OK
new Model("World", null, 20) // Exception because null address.
假设我有一个没有任何构造函数的模型类,因为我需要 在许多不同的逻辑中初始化它。但我有一个非空的 关键词

您需要注意的是,即使您不编写任何构造函数,编译器也将提供一个默认的无参数构造函数,它将自动将对象中的所有字段初始化为默认值(即,
String
类型为
null
int
类型为零值,等等)


类构造函数是验证是否提供了所有必填字段的正确位置,因此创建自己的构造函数以检查在对象创建过程中传入的所有必填字段

public class Model {
    private String name;
    private String address;
    private int age;

    public Model(String name, String address, int age) {
         if(name == null) { 
               throw new IllegalArgumentException(" Name is mandatory ");
         } 
         if(address == null) { 
               throw new IllegalArgumentException(" Address is mandatory ");
         }
         if(age < 0) { 
               throw new IllegalArgumentException(" Age is Invalid ");
         }
         this.name = name;
         this.address = address;
         this.age = age;
    }
   //Add getters and setters
}
公共类模型{
私有字符串名称;
私有字符串地址;
私人互联网;
公共模型(字符串名称、字符串地址、整数){
如果(name==null){
抛出新的IllegalArgumentException(“名称为必填项”);
} 
如果(地址==null){
抛出新的IllegalArgumentException(“地址是必需的”);
}
如果(年龄<0){
抛出新的IllegalArgumentException(“年龄无效”);
}
this.name=名称;
this.address=地址;
这个。年龄=年龄;
}
//添加getter和setter
}


另外,通过标记字段
private
(如上所示)来封装
模型
类的数据。如果它们是final,则必须在构造函数中对它们进行初始化。当您将它们声明为
final String a=“a”
、在每个构造函数中声明为
a=“a”
或在实例初始值设定项块中声明为
{a=“a”}
时,需要对它们进行初始化,否则会出现编译时错误。您当前设置
final
的方式没有意义,因为您不需要初始化它们,这将与
final
的用途相矛盾。以及“但是我有一个新的关键字say notnull”lol..用于编辑:这是java而不是sql表。java中没有
notNull
或类似的东西。最相似的是
final
,它注定要初始化,其中
null
是不被禁止的…@RC。关键字final会让其他人教我java基本功。这不是我要问的-p对于仍在学习Java基础知识的人来说,这可能不是一个合适的答案。@ajb实际上我有JSON解析器、HTTP服务器和许多其他由我自己用纯Java构建的工具。我的意思是,我认为这不是一个基本问题-P@tabiul谢谢你的回答,我期待更多语法级别的解决方案(编译时签入)。你的答案实际上是一个工厂设计模式,这意味着我应该编写另一个类,它不会在编译时签入。啊,好的,那么你想要一些新的关键字
notnull
。嗯,我可能错了,但我认为你想要的在Java中是不可能的。也许你应该使用Scala:)因为那边有
案例类
,你可以使用
val
var
@G.Bob,但你可以使用注释。不确定您使用的是什么IDE,但Intellij IDEA内置了
@NotNull
@Nullable
注释。您还可以为其他IDE构建自己的注释和注释处理器。