Java的最终版本与C++的const

Win*_*Win 144 c++ java final const

Java进行C++程序员教程说,(大亮点是我自己的):

关键字final 大致 相当于C++中的const

在这种情况下,"大致"意味着什么?它们不完全一样吗?

有什么区别,如果有的话?

Fle*_*exo 185

在C++中,标记成员函数const意味着可以在const实例上调用它.Java没有与之相当的东西.例如:

class Foo {
public:
   void bar();
   void foo() const;
};

void test(const Foo& i) {
   i.foo(); //fine
   i.bar(); //error
}
Run Code Online (Sandbox Code Playgroud)

可以在Java中稍后分配值,例如:

public class Foo {
   void bar() {
     final int a;
     a = 10;
   }
}
Run Code Online (Sandbox Code Playgroud)

在Java中是合法的,但不是C++而是:

public class Foo {
   void bar() {
     final int a;
     a = 10;
     a = 11; // Not legal, even in Java: a has already been assigned a value.
   }
}
Run Code Online (Sandbox Code Playgroud)

在Java和C++中,成员变量可以分别为final/ const.这些需要在类的实例构建完成时给出一个值.

在Java中,必须在构造函数完成之前设置它们,这可以通过以下两种方式之一来实现:

public class Foo {
   private final int a;
   private final int b = 11;
   public Foo() {
      a = 10;
   }
}
Run Code Online (Sandbox Code Playgroud)

在C++中,您需要使用初始化列表为const成员提供值:

class Foo {
   const int a;
public:
   Foo() : a(10) {
      // Assignment here with = would not be legal
   }
};
Run Code Online (Sandbox Code Playgroud)

在Java中,final可用于将事物标记为不可覆盖.C++(pre-C++ 11)不会这样做.例如:

public class Bar {
   public final void foo() {
   }
}

public class Error extends Bar {
   // Error in java, can't override
   public void foo() {
   }
}
Run Code Online (Sandbox Code Playgroud)

但在C++中:

class Bar {
public:
   virtual void foo() const {
   }
};

class Error: public Bar {
public:
   // Fine in C++
   virtual void foo() const {
   }
};
Run Code Online (Sandbox Code Playgroud)

这很好,因为标记成员函数的语义const是不同的.(您也可以通过仅使用其中一个成员函数来重载const.(另请注意,C++ 11允许将成员函数标记为final,请参阅C++ 11更新部分)


C++ 11更新:

事实上,C++ 11允许您将类和成员函数标记为final与Java中的相同特性具有相同的语义,例如在Java中:

public class Bar {
   public final void foo() {
   }
}

public class Error extends Bar {
   // Error in java, can't override
   public void foo() {
   }
}
Run Code Online (Sandbox Code Playgroud)

现在可以用C++ 11编写为:

class Bar {
public:
  virtual void foo() final;
};

class Error : public Bar {
public:
  virtual void foo() final;
};
Run Code Online (Sandbox Code Playgroud)

我必须使用预发布的G ++ 4.7编译这个例子.请注意,const在这种情况下,这不会替换,而是对其进行扩充,从而提供类似Java的行为,而这种行为与最接近的等效C++关键字一样.所以,如果你想要一个成员函数final,const你会这样做:

class Bar {
public:
  virtual void foo() const final;
};
Run Code Online (Sandbox Code Playgroud)

(此处的顺序constfinal此处是必需的).

以前没有const成员函数的直接等价,尽管使函数非virtual可能是一个潜在的选项,尽管在编译时不会导致错误.

同样是Java:

public final class Bar {
}

public class Error extends Bar {
}
Run Code Online (Sandbox Code Playgroud)

变成了C++ 11:

class Bar final {
};

class Error : public Bar {
};
Run Code Online (Sandbox Code Playgroud)

(以前的private构造函数可能是你在C++中最接近的构造函数)

有趣的是,为了保持与前C++ 11代码的向后兼容性,代码final 不是通常的关键字.(以简单,合法的C++ 98为例struct final;,了解为什么将其作为关键字会破坏代码)

  • 你应该把这些方法变成虚拟的; 否则,你真的不是在做同样的事情 (3认同)
  • 请注意,为了这个目的,C++ 0x添加了`final`成员函数装饰器.VC++ 2005,2008和2010已经实现了这一点,使用了contextual关键字`sealed`而不是`final`. (2认同)

Ral*_*lph 30

在Java中,final关键字可用于四件事:

  • 在类或方法上密封它(不允许子类/覆盖)
  • 在一个成员变量上声明它可以设置一次(我想这就是你在说的)
  • 在方法中声明的变量上,以确保它可以设置一次
  • 在方法参数上,声明它不能在方法中修改

一个重要的事情是:Java最终成员变量必须设置一次!例如,在构造函数,字段声明或初始化器中.(但是你不能在方法中设置最终的成员变量).

使成员变量最终的另一个结果与内存模型有关,如果您在线程环境中工作,这很重要.


Blu*_*eft 25

一个const对象只能调用const方法,并且通常被认为是不可变的.

const Person* person = myself;
person = otherPerson; //Valid... unless we declared it const Person* const!
person->setAge(20); //Invalid, assuming setAge isn't a const method (it shouldn't be)
Run Code Online (Sandbox Code Playgroud)

一个final对象不能被设置为一个新的对象,但它不是一成不变的-没有什么从调用任何停止的人set的方法.

final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Run Code Online (Sandbox Code Playgroud)

Java没有固有的方法来声明对象不可变; 你需要将类设计为不可变的.

当变量是基本类型时,final/ const工作相同.

const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Run Code Online (Sandbox Code Playgroud)

  • 这也是一个很好的答案(就像这里的许多其他人一样).不幸的是,我只能接受一个答案.:) (3认同)

Jam*_*hek 12

Java final相当于原始值类型的C++ const.

对于Java引用类型,final关键字等效于const指针...即

//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();

//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
Run Code Online (Sandbox Code Playgroud)


poc*_*ora 8

你已经有了一些很好的答案,但有一点似乎值得补充:const在C++中常用来防止程序的其他部分改变对象的状态.正如已经指出的那样,final在java中不能这样做(除了原语) - 它只是阻止引用被改为不同的对象.但是,如果您使用的是a Collection,则可以使用静态方法阻止对对象的更改

 Collection.unmodifiableCollection( myCollection ) 
Run Code Online (Sandbox Code Playgroud)

这将返回一个Collection引用,该引用提供对元素的读访问,但如果尝试修改则抛出异常,使其有点像const在C++中


jos*_*efx 7

Java final仅适用于原始类型和引用,而不适用于const关键字适用于任何事物的对象实例本身.

比较const list<int> melist;final List<Integer> melist;第一使其无法修改列表,而后者只阻止你分配一个新的列表melist.