sirven - palabras reservadas en java y su significado
La final de Java contra la const de C++ (11)
¡Además de tener ciertas y sutiles propiedades de subprocesamiento múltiple , las variables declaradas final
no necesitan ser inicializadas en la declaración!
es decir, esto es válido en Java:
// declare the variable
final int foo;
{
// do something...
// and then initialize the variable
foo = ...;
}
Esto no sería válido si se escribe con la const
C ++
El tutorial de Java para C ++ programadores dice que (destacar es mío):
La palabra clave final es más o menos equivalente a const en C ++
¿Qué significa "aproximadamente" en este contexto? ¿No son exactamente lo mismo?
¿Cuáles son las diferencias, si las hay?
De acuerdo con wikipedia :
- En C ++, un campo const no solo está protegido de reasignación, sino que existe la limitación adicional de que solo se pueden invocar los métodos const y solo se puede pasar como el argumento const de otros métodos.
- Las clases internas no estáticas pueden acceder libremente a cualquier campo de la clase envolvente, final o no.
En Java, la palabra clave final se puede usar para cuatro cosas:
- en una clase o método para sellarlo (no se permiten subclases / anulación)
- en una variable miembro para declarar que se puede establecer exactamente una vez (creo que esto es de lo que estás hablando)
- en una variable declarada en un método, para asegurarse de que se puede establecer exactamente una vez
- en un parámetro de método, para declarar que no se puede modificar dentro del método
Una cosa importante es: ¡una variable de miembro final de Java debe establecerse exactamente una vez! Por ejemplo, en un constructor, declaración de campo o inicializador. (Pero no puede establecer una variable miembro final en un método).
Otra consecuencia de hacer que un miembro sea variable final se relaciona con el modelo de memoria, que es importante si trabajas en un entorno enhebrado.
Java final es equivalente a C ++ const en tipos de valores primitivos.
Con los tipos de referencia de Java, la palabra clave final es equivalente a un puntero const ... es decir,
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
Javas final solo funciona en tipos primitivos y referencias, nunca en instancias de objetos donde la palabra clave const funciona en cualquier cosa.
comparar const list<int> melist;
con el final List<Integer> melist;
el primero hace que sea imposible modificar la lista, mientras que el último solo le impide asignar una nueva lista a Melist.
Permítanme explicar lo que entendí con un ejemplo de declaración de cambio / caso.
Los valores en cada declaración de caso deben ser valores constantes de tiempo de compilación del mismo tipo de datos que el valor de conmutación.
declare algo como a continuación (ya sea en su método como instancias locales, o en su clase como variable estática (luego agregue static a él), o una variable de instancia.
final String color1 = "Red";
y
static final String color2 = "Green";
switch (myColor) { // myColor is of data type String
case color1:
//do something here with Red
break;
case color2:
//do something with Green
break;
}
Este código no se compilará si color1
es una variable de clase / instancia y no una variable local. Esto se compilará si color1
se define como estática final (luego se convierte en variable final estática).
Cuando no se compila, obtendrá el siguiente error
error: constant string expression required
Supongo que dice "aproximadamente" porque el significado de const
en C ++ se complica cuando hablamos de punteros, es decir punteros constantes contra punteros a objetos constantes. Como no hay punteros "explícitos" en Java, final
no tiene estos problemas.
Un objeto const
solo puede llamar a métodos const
, y generalmente se considera inmutable.
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)
Un objeto final
no se puede establecer en un objeto nuevo, pero no es inmutable; no hay nada que impida que alguien llame a ningún método set
.
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Java no tiene una forma inherente de declarar objetos inmutables; necesita diseñar la clase como inmutable usted mismo.
Cuando la variable es un tipo primitivo, final
/ const
funcionan de la misma manera.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
Ya tiene algunas respuestas excelentes, pero merece la pena agregar un punto: const
en C ++ se usa comúnmente para evitar que otras partes del programa cambien el estado de los objetos. Como se ha señalado, el final
en Java no puede hacer esto (excepto en el caso de las primitivas), solo evita que la referencia se cambie a un objeto diferente. Pero si está utilizando una Collection
, puede evitar cambios en sus objetos utilizando el método estático
Collection.unmodifiableCollection( myCollection )
Esto devuelve una referencia de Collection
que proporciona acceso de lectura a los elementos, pero arroja una excepción si se intentan modificaciones, lo que lo hace un poco como const
en C ++
la palabra clave "const" significa que su variable se guarda en la ROM (con microprocesador). en la computadora, su variable se guarda en el área de RAM para el código de ensamblaje (solo lectura de RAM). significa que su variable no se encuentra en la memoria RAM que se puede incluir incluyen: memoria estática, memoria de pila y memoria de pila.
la palabra clave "final" significa que su variable se guarda en RAM escribible, pero observará al compilador que su variable solo cambia una vez.
//in java language you can use:
static final int i =10;
i =11; //error is showed here by compiler
//the same in C++ the same as follows
int i =10;
const int &iFinal = i;
iFinal = 11; //error is showed here by compiler the same as above
Creo que "const" es malo en rendimiento, por lo que Java no lo usa.
En C ++ marcar una función de miembro const
significa que se puede const
instancias const
. Java no tiene un equivalente a esto. P.ej:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Los valores se pueden asignar, una vez, más tarde en Java, por ejemplo:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
es legal en Java, pero no en C ++, mientras que:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Tanto en Java como en C ++ las variables miembro pueden ser final
/ const
respectivamente. Estos deben tener un valor para el momento en que una instancia de la clase termine de construirse.
En Java deben establecerse antes de que el constructor haya terminado, esto se puede lograr de una de estas dos maneras:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
En C ++ necesitarás usar listas de inicialización para darles a los miembros de const
un valor:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
En Java final se puede usar para marcar cosas como no reemplazables. C ++ (pre-C ++ 11) no hace esto. P.ej:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can''t override
public void foo() {
}
}
Pero en C ++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
esto está bien, porque la semántica de marcar una función de const
es diferente. (También podría sobrecargar al tener solo const
en una de las funciones miembro. (Tenga en cuenta también que C ++ 11 permite que las funciones miembro se marquen como definitivas, consulte la sección de actualización C ++ 11)
Actualización de C ++ 11:
C ++ 11 de hecho le permite marcar tanto las clases como las funciones miembro como final
, con semántica idéntica a la misma característica en Java, por ejemplo en Java:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can''t override
public void foo() {
}
}
Ahora se puede escribir exactamente en C ++ 11 como:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Tuve que compilar este ejemplo con un prelanzamiento de G ++ 4.7. Tenga en cuenta que esto no reemplaza a const
en este caso, sino que lo aumenta, proporcionando el comportamiento similar a Java que no se vio con la palabra clave C ++ equivalente más cercana. Entonces, si quisieras que una función de miembro fuera final
y const
, harías:
class Bar {
public:
virtual void foo() const final;
};
(El orden de const
y final
aquí es obligatorio).
Anteriormente no existía un equivalente directo de las funciones de miembros de la const
, aunque la creación de funciones no virtual
constituiría una opción potencial, aunque sin causar un error en tiempo de compilación.
Del mismo modo, el Java:
public final class Bar {
}
public class Error extends Bar {
}
se convierte en C ++ 11:
class Bar final {
};
class Error : public Bar {
};
(Probablemente, constructores private
fueron lo más cercano que se podía llegar a esto en C ++)
Curiosamente, para mantener la compatibilidad con versiones anteriores al código C ++ 11, el final
no es una palabra clave de la forma habitual. (Tome el trivial y legal C ++ 98 example struct final;
para ver por qué convertirlo en una palabra clave rompería el código)