初始化抽象类(Java)中的最终变量

初始化抽象类(Java)中的最终变量,java,class,variables,abstract,final,Java,Class,Variables,Abstract,Final,所以我有一个抽象类 public abstract class A { protected final boolean b; protected A (boolean b){ this.b = b; } } 这个类扩展了 public class C extends A{ protected C() { super(false); } } 我不希望“b”在初始化后能够更改其值 但是我不知道如何在编译器没有失控的情况下完成它 欢迎提出任

所以我有一个抽象类

 public abstract class A {

   protected final boolean b;

   protected A (boolean b){
    this.b = b;
   }

}
这个类扩展了

 public class C extends A{

   protected C() {
    super(false);
   }
}

我不希望“b”在初始化后能够更改其值 但是我不知道如何在编译器没有失控的情况下完成它

欢迎提出任何建议。提前谢谢

编辑1:从b中删除静态

编辑2:确定问题已解决,请参见上文。
特别感谢J.Lucky:)

解决方案:您应该将布尔值更改为布尔值,使其私有化,提供一个getter和一个受保护的setter。在setter中,您应该检查布尔值是否已初始化。如果是这样,您应该忽略重置,或者抛出和异常解决方案:您应该将布尔值更改为布尔值,使其私有,提供一个getter和一个受保护的setter。在setter中,您应该检查布尔值是否已初始化。如果是这样,您应该忽略重置,或者抛出和异常解决方案:您应该将布尔值更改为布尔值,使其私有,提供一个getter和一个受保护的setter。在setter中,您应该检查布尔值是否已初始化。如果是这样,您应该忽略重置,或者抛出和异常解决方案:您应该将布尔值更改为布尔值,使其私有,提供一个getter和一个受保护的setter。在setter中,您应该检查布尔值是否已初始化。如果是这样,您应该忽略重置,或者抛出和异常

我建议您使用
final
关键字

请尝试以下代码:

abstract class A {

    final protected boolean b;

    A(boolean b) {
        this.b = b;
    }

    //No setter method
    //public abstract void setB(boolean b);
    public abstract boolean getB();
}

class C extends A {

    C(boolean b) {
        super(b);
    }

    @Override
    public boolean getB() {
        return b;
    }
}
示例实施将是:

public static void main(String args[]) {
    C c = new C(true);
    System.out.println(c.getB());
}
由于
b
现在是一个
final
变量,您将被迫在构造函数上初始化它,并且您将无法再更改
b
。即使您为
b
提供了setter方法,编译器也会阻止您

编辑2:

假设您创建了另一个名为“D”的类,这一次您知道您希望在默认情况下将其设置为
false
。您可以选择以下内容:

class D extends A {
    D() {
        super(false);
    }

    //You can also overload it so that you will have a choice
    D(boolean b) {
        super(b);
    }


    @Override
    public boolean getB() {
        return b;
    }

    public static void main(String[] args) {
        D defaultBVal = D();
        D customBVal = D(true);

        System.out.println(defaultBVal.getB()); //false
        System.out.println(customBVal.getB()); //true
    }
}

我建议您使用
final
关键字

请尝试以下代码:

abstract class A {

    final protected boolean b;

    A(boolean b) {
        this.b = b;
    }

    //No setter method
    //public abstract void setB(boolean b);
    public abstract boolean getB();
}

class C extends A {

    C(boolean b) {
        super(b);
    }

    @Override
    public boolean getB() {
        return b;
    }
}
示例实施将是:

public static void main(String args[]) {
    C c = new C(true);
    System.out.println(c.getB());
}
由于
b
现在是一个
final
变量,您将被迫在构造函数上初始化它,并且您将无法再更改
b
。即使您为
b
提供了setter方法,编译器也会阻止您

编辑2:

假设您创建了另一个名为“D”的类,这一次您知道您希望在默认情况下将其设置为
false
。您可以选择以下内容:

class D extends A {
    D() {
        super(false);
    }

    //You can also overload it so that you will have a choice
    D(boolean b) {
        super(b);
    }


    @Override
    public boolean getB() {
        return b;
    }

    public static void main(String[] args) {
        D defaultBVal = D();
        D customBVal = D(true);

        System.out.println(defaultBVal.getB()); //false
        System.out.println(customBVal.getB()); //true
    }
}

我建议您使用
final
关键字

请尝试以下代码:

abstract class A {

    final protected boolean b;

    A(boolean b) {
        this.b = b;
    }

    //No setter method
    //public abstract void setB(boolean b);
    public abstract boolean getB();
}

class C extends A {

    C(boolean b) {
        super(b);
    }

    @Override
    public boolean getB() {
        return b;
    }
}
示例实施将是:

public static void main(String args[]) {
    C c = new C(true);
    System.out.println(c.getB());
}
由于
b
现在是一个
final
变量,您将被迫在构造函数上初始化它,并且您将无法再更改
b
。即使您为
b
提供了setter方法,编译器也会阻止您

编辑2:

假设您创建了另一个名为“D”的类,这一次您知道您希望在默认情况下将其设置为
false
。您可以选择以下内容:

class D extends A {
    D() {
        super(false);
    }

    //You can also overload it so that you will have a choice
    D(boolean b) {
        super(b);
    }


    @Override
    public boolean getB() {
        return b;
    }

    public static void main(String[] args) {
        D defaultBVal = D();
        D customBVal = D(true);

        System.out.println(defaultBVal.getB()); //false
        System.out.println(customBVal.getB()); //true
    }
}

我建议您使用
final
关键字

请尝试以下代码:

abstract class A {

    final protected boolean b;

    A(boolean b) {
        this.b = b;
    }

    //No setter method
    //public abstract void setB(boolean b);
    public abstract boolean getB();
}

class C extends A {

    C(boolean b) {
        super(b);
    }

    @Override
    public boolean getB() {
        return b;
    }
}
示例实施将是:

public static void main(String args[]) {
    C c = new C(true);
    System.out.println(c.getB());
}
由于
b
现在是一个
final
变量,您将被迫在构造函数上初始化它,并且您将无法再更改
b
。即使您为
b
提供了setter方法,编译器也会阻止您

编辑2:

假设您创建了另一个名为“D”的类,这一次您知道您希望在默认情况下将其设置为
false
。您可以选择以下内容:

class D extends A {
    D() {
        super(false);
    }

    //You can also overload it so that you will have a choice
    D(boolean b) {
        super(b);
    }


    @Override
    public boolean getB() {
        return b;
    }

    public static void main(String[] args) {
        D defaultBVal = D();
        D customBVal = D(true);

        System.out.println(defaultBVal.getB()); //false
        System.out.println(customBVal.getB()); //true
    }
}
那么这个呢:

public abstract class A {

   private static Boolean b;

   //setB is declared here and, depending on the class that implements it, 
   //it initializes the value of the variable "b"

   protected abstract void setB();

}

public class C extends A{

   protected void setB() {
     if(b != null) b = true;
   }
}
现在,变量在被调用时只初始化一次。还有一些问题。有人可以使用反射来改变值。此外,当对象序列化时,可能有人会更改值。如果有多个线程访问该方法,则应同步该方法。但是,如果这些都不是问题,那么这个解决方案可能适合您。

那么这个呢:

public abstract class A {

   private static Boolean b;

   //setB is declared here and, depending on the class that implements it, 
   //it initializes the value of the variable "b"

   protected abstract void setB();

}

public class C extends A{

   protected void setB() {
     if(b != null) b = true;
   }
}
现在,变量在被调用时只初始化一次。还有一些问题。有人可以使用反射来改变值。此外,当对象序列化时,可能有人会更改值。如果有多个线程访问该方法,则应同步该方法。但是,如果这些都不是问题,那么这个解决方案可能适合您。

那么这个呢:

public abstract class A {

   private static Boolean b;

   //setB is declared here and, depending on the class that implements it, 
   //it initializes the value of the variable "b"

   protected abstract void setB();

}

public class C extends A{

   protected void setB() {
     if(b != null) b = true;
   }
}
现在,变量在被调用时只初始化一次。还有一些问题。有人可以使用反射来改变值。此外,当对象序列化时,可能有人会更改值。如果有多个线程访问该方法,则应同步该方法。但是,如果这些都不是问题,那么这个解决方案可能适合您。

那么这个呢:

public abstract class A {

   private static Boolean b;

   //setB is declared here and, depending on the class that implements it, 
   //it initializes the value of the variable "b"

   protected abstract void setB();

}

public class C extends A{

   protected void setB() {
     if(b != null) b = true;
   }
}

现在,变量在被调用时只初始化一次。还有一些问题。有人可以使用反射来改变值。此外,当对象序列化时,可能有人会更改值。如果有多个线程访问该方法,则应同步该方法。但是,如果这些都不是问题,那么这个解决方案可能适合您。

为什么静态变量由实例方法设置?这听起来是个坏主意。如果你能给出一个让这个设计正常工作的原因,这会很有帮助。基本上,它是一个变量,每个子类中都会出现,但每个子类中都可能有不同的值编辑:我添加了static,因为编译器基本上在抱怨,那么一个静态变量对你没有任何帮助