Java &引用;常数;在爪哇
我有一个关于java中“CONST”的问题 我想知道如何用C语言制作类似“const struct VAL&getVal()”的代码 下面是示例代码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 =
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,那么他的代码将在运行时崩溃?如果问题是它属于不应在外部更改的数据结构,那么您可以返回该结构的副本,而不是结构本身,因此返回的结构中的更改不会影响主数据结构。的可能副本