Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;常数;在爪哇_Java - Fatal编程技术网

Java &引用;常数;在爪哇

Java &引用;常数;在爪哇,java,Java,我有一个关于java中“CONST”的问题 我想知道如何用C语言制作类似“const struct VAL&getVal()”的代码 下面是示例代码 public class test { /* VAL is just structure-like class */ class VAL { public int i; }; private VAL val; /* test class functions */ test() { val =

我有一个关于java中“CONST”的问题

我想知道如何用C语言制作类似“const struct VAL&getVal()”的代码

下面是示例代码

public class test {
   /* VAL is just structure-like class */
   class VAL {
    public int i;
   };
   private VAL  val;

   /* test class functions */
   test() {
    val = new VAL();
    val.i = 1;
   }

   VAL getVal() {
    return val;
   }

   /* main function */
   public static void main(String[] args) {
    test t = new test();
    VAL  t_val;

    t_val = t.getVal();

    t_val.i = 2; /* it should be error if t_val variable is a const */
    System.out.printf("%d %d\n", t.getVal().i, t_val.i);
   }
}
struct VAL
{
    int i;
};

const struct VAL &getVal() /* THIS IS WHAT I WANT */
{
    static VAL xxx;
    return xxx;
}

int main()
{
    const VAL &val = getVal();
    val.i = 0; /* error */

    VAL val2 = getVal();
    val2.i = 0; /* it's not an error, but it's ok because it cannot be changed xxx variable in getVal() either. */

    return 0;
}
下面是C示例代码

public class test {
   /* VAL is just structure-like class */
   class VAL {
    public int i;
   };
   private VAL  val;

   /* test class functions */
   test() {
    val = new VAL();
    val.i = 1;
   }

   VAL getVal() {
    return val;
   }

   /* main function */
   public static void main(String[] args) {
    test t = new test();
    VAL  t_val;

    t_val = t.getVal();

    t_val.i = 2; /* it should be error if t_val variable is a const */
    System.out.printf("%d %d\n", t.getVal().i, t_val.i);
   }
}
struct VAL
{
    int i;
};

const struct VAL &getVal() /* THIS IS WHAT I WANT */
{
    static VAL xxx;
    return xxx;
}

int main()
{
    const VAL &val = getVal();
    val.i = 0; /* error */

    VAL val2 = getVal();
    val2.i = 0; /* it's not an error, but it's ok because it cannot be changed xxx variable in getVal() either. */

    return 0;
}

使用
final
关键字。它类似于
const

final
关键字,具有相似的语义。您不能更改对象的引用,但如果对象是可变的,则可以更改对象本身。我建议用谷歌搜索它并阅读更多关于它的信息。

更好的方法是使用enum。他们非常强大。 您可以在switch语句中使用它,并且可以根据需要使用struct的内部属性。
您可以在上查找文档。

您不能像在C中那样做完全相同的事情。即使您使用
final
关键字,它也只能阻止修改变量引用
t_val.i=2如果将i声明为final属性,则将是错误的。

将val的成员变量设置为private,并提供公共getter。如果您仍然希望其他人能够在初始化后更改成员,那么可以使用仅包含getter的接口,以及包含公共setter的实现类。然后,返回类的接口,以便调用方不能更改其成员

interface ValGetters {
   public int getI();
}

class Val implements ValGetters {
   private int i;
   public int getI() { return i; }
   public void setI(int ii) { i = ii; }
}
在内部,持有Val。当你想让其他人使用它时,以VALGETERS的身份返回

const struct VAL&getVal()/*这是 我想要什么*/


Java中没有这样的结构,尽管所有答案都与之相反,尤其是那些建议使用“final”关键字的答案。

简而言之,你不能,至少在一般意义上不能。如果您使用所有基本体(或者您创建的类都是基本体)和非常少的类(我想到的是字符串),您可以这样做,但是您不能在一般意义上这样做,因为您无法控制人们在调用getter方法后对对象所做的操作。如果要执行此操作,您有两个选项:

  • 将所有字段(不是您的类,是您的字段,在本例中是i)设置为最终字段,这样人们就无法更改它们

  • 将所有字段设置为私有,不要创建任何公共setter(这是首选方法)

  • 然而,回到我最初的观点:

    假设val的定义如下:

    public class VAL {
            private List<Integer> i=new ArrayList<Integer>();
            public VAL() {
                i.add(3);
             }
            public List<Integer> getI() {return i;}
           };
    
    上面的代码将打印出来 1. 0


    这意味着,虽然我没有更改,但您的列表内容却更改了……。

    这与变量定义无关。请注意,对象需要是不可变的(如果不创建新的对象状态,就无法更改对象状态)。这是关于变量由函数返回的。这是正确的。决赛和康斯特一样。检查医生!错。读一下这个——代码只是一个简单的版本。真正的代码比它更复杂。我真正想要的是由函数返回的CONST-STRUCT_变量。你可以用枚举实现它,就像你写的那样。这些是有点复杂的枚举。我不想更改返回变量。我想阻止更改返回值。@kellinggun您指的是对象引用还是基元值。在对象引用的情况下,我看到的唯一方法是使这个类不可变。将所有字段和setter方法设置为私有。这样你就会确信没有人能改变它。如果您指的是基元值,则它们总是按值传递。“final关键字具有类似的语义”:不,它没有。java中没有C++引用,而‘最后’有不同于“const &”的语义。回答错误。@EJP类似但不完全相同。如果在原语上使用
    final
    ,其效果与const相同。我又错了吗?真的不一样。”const'影响调用序列签名;'最终的“没有”const'可以与Java中不存在的'&'一起使用。相似之处少于不同之处。关于你的答案,我还有一个问题。我可以尝试从ValGetter对象到Val对象的类型转换吗?就像这个“Val Val=(Val)valgetter;”@killinggun是的,你可以做到。但是,如果您担心有人试图破解您的代码,您可以将
    class Val
    设置为私有,将
    interface ValGetters
    设置为公共。这样,假设Val是嵌套的,那么只能从嵌套类中使用Val(也可以将其设置为常规类,但不能设置为公共类,因此只能从包中访问)。但无论如何,OOP是关于合同的。如果有人将其转换回Val,然后您将ValGetters的实现类更改为Val2,那么他的代码将在运行时崩溃?如果问题是它属于不应在外部更改的数据结构,那么您可以返回该结构的副本,而不是结构本身,因此返回的结构中的更改不会影响主数据结构。的可能副本