Is there a solution to use a final variable in a Java constructor?
The problem is that if I initialize a final field like:
private final String name = "a name";
then I cannot use it in the constructor. Java first runs the constructor and then the fields. Is there a solution that allows me to access the final field in the constructor?
I do not really understand your question. That
public class Test3 {
private final String test = "test123";
public Test3() {
System.out.println("Test = "+test);
}
public static void main(String[] args) {
Test3 t = new Test3();
}
}
executes as follows:
$ javac Test3.java && java Test3
Test = test123
Do the initialization in the constructor, e.g.,
private final String name;
private YourObj() {
name = "a name";
}
Of course, if you actually know the value at variable declaration time, it makes more sense to make it a constant, e.g.,
private static final String NAME = "a name";
We're getting away from the question.
Yes, you can use a private final variable. For example:
public class Account {
private final String accountNumber;
private final String routingNumber;
public Account(String accountNumber, String routingNumber) {
this.accountNumber = accountNumber;
this.routingNumber = routingNumber;
}
}
What this means is that the Account class has a dependency on the two Strings, account and routing numbers. The values of these class attributes MUST be set when the Account class is constructed, and these number cannot be changed without creating a new class.
The 'final' modifier here makes the attributes immutable.
Marking it static, will allow you to use it in the constructor, but since you made it final, it can not be changed.
private static final String name = "a_name";
is is possible to use a static init block as well.
private static final String name;
static { name = "a_name"; }
If you are trying to modify the value in the constructor, then you can't assign a default value or you have to make it not final.
private String name = "a_name";
Foo( String name )
{
this.name = name;
}
or
private final String name;
Foo( String name )
{
if( s == null )
this.name = "a_name";
else
this.name = name;
}
In this case, you can mark the field as 'static' also.
Another possiblity is to initialize the field in an instance initializer blocK:
public class Foo {
final String bar;
{
System.out.println("initializing bar");
bar = "created at " + System.currentTimeMillis();
}
public Foo() {
System.out.println("in constructor. bar=" + bar);
}
public static void main(String[] args) {
new Foo();
}
}
In that case, you might as well make it static, too. And Java convention is to name such constants in ALL_CAPS.
private static final String name = getName();
where getName() is a static function that gets you the name.
I cannot use it in the constructor, while java first runs the constructor an then the fields...
This is not correct, fields are evaluated first, otherwise you couldn't access any default values of members in your constructors, since they would not be initialized. This does work:
public class A {
protected int member = 1;
public A() {
System.out.println(member);
}
}
The keyword final merely marks the member constant, it is treated as any other member otherwise.
EDIT: Are you trying to set the value in the constructor? That wouldn't work, since the member is immutable if defined as final.
Related
I'm a beginner in Java and I was typing this block of code in Eclipse and it is throwing errors like this. I haven't even started anything yet, but there's error with my variable name? I know Eclipse is very particular about duplicate variable names in maybe the same package or something. Is that maybe where the problem is?
Thanks!
You need to either declare those variables outside the main method (if you want them to have class scope), or remove the private keyword if you want them to have method scope, i.e. just in your main method.
So either this:
public class Person {
private String name;
// other variables...
public static void main(String[] arguments) {
// other code...
}
}
Or like this:
public class Person {
public static void main(String[] arguments) {
String name;
// other variables and code...
}
}
You can not use the access modifier private inside any method. Remove the access modifier private before the variable name.
Or you can declare these variable in class level (that is as instance variables) - outside of any methods. Since the name is a property/attribute of a Person, according to OOP it is better to keep the name as field of the Person class like this -
public class Person{
private String name;
//Other property of Person
public String getName(){
return name;
}
public String setName(String name){
this.name = name;
}
public static void main(String[] args){
}
}
Use public getter and setter method to access these private variable from outside of the Person class.
Either do this:
public class Person {
private String name; // Declared as an attribute of Person class
public static void main(String [] args) { ...}
}
Or this:
public class Person {
public static void main(String [] args) {
String name; // No private
// ...
}
}
Just remove the access modifier private in both the variables.Your problem
will be solved.You cannot declare private variables inside methods.
I have defined a class
class Prop{
public static enum property{
NAME,
CITY,
ADDRESS;
}
private String NAME;
private String CITY;
private String ADDRESS;
public String getValue(property pro){
switch(pro){
case NAME:
return NAME;
case CITY:
return CITY;}
return null;}
}
class CallPro{
private String name;
name=Prop.getValue("");
}
I am not exactly getting how to call getValue from class CallPro.
Basically what parameters should be passed to get the desired value.
I am a beginner in java
To run this program you need a public static void main(String[]) method first. That's your entry point into any Java program. Since, you want to assign the values inside callPro, add the main() method there.
Next, you want to call getProperty() which is an instance method belonging to class prop, so you'll need to create an instance of it first using the new constructor() syntax.
class callPro {
private static String name;
private static String city;
private static String address;
public static void main(String[] args) {
// create prop instance
prop property = new prop();
// call prop's method getValue()
name = property.getValue(prop.property.CITY);
city = property.getValue(prop.property.NAME);
address = property.getValue(prop.property.ADDRESS);
// New York, John, Central Park
System.out.println(name + ", " + city + ", " + address);
}
}
Notice, how I had to make callPro's members static to be able to access them inside the main() method because that's static too. Also, note how I referenced the Enums: className.enumType.enumValue.
To be able to see the values print from the main() method, you'll also need to provide values for your prop class members as
private String NAME = "John";
private String CITY = "New York";
private String ADDRESS = "Central Park";
public String getValue(property pro) {
switch (pro) {
case NAME:
return NAME;
case CITY:
return CITY;
case ADDRESS:
return ADDRESS;
}
return null;
}
Yes, you can loop through an enum's values and retrieve your properties in a loop as
prop property = new prop();
for (prop.property prop : prop.property.values()) {
System.out.println(property.getValue(prop));
}
enumType.values() returns an enumType[] of all enumValues which can be used with a for-each loop as shown above.
public class Wrapper {
public Wrapper(final String name, final String email) {
_name= name;
_email = email;
}
private static final Card testCard = new Card(_email, _name);
private final static String _name;
private final static String _email;
}
I would like the instantiate this class providing a name and an email.
I am getting "Cannot reference a variable before it is defined for (_email, _name) variables on line :
private static final Card testCard = new Card(_email, _name);
I can make it work by moving the declarations to the top but is there any other way?
Thanks
Based on your description, I don't think you want to use static.
I would like the instantiate this class providing a name and an email.
That means that you provide a name and an e-mail when creating an instance of the class. But using static means that there is only one name and one e-mail, that all instances of the class share! Unless every person in your universe has the same name and the same e-mail address, that is not what you want. So get rid of static on _name, _email, and testCard.
Also, initializing testCard outside the constructor won't work, because the program will try to do new Card(_email, _name) before _email and _name have been initialized. So change that to
private final Card testCard;
and in the constructor:
testCard = new Card(_email, _name);
after _email and _name have been set.
If you do this, you should be able to put the declarations anywhere you want. The "Cannot reference a variable before it is defined" or "Illegal forward reference" problems only come up when you have global (static) variables, according to this question.
You cann't initialize static field because variables _email and _name are not initialized yet. You should initialize testCard after _email and _name will be initialized.
For example, you can do it in constructor
public Wrapper(final String name, final String email)
{
_name= name;
_email = email;
testCard = new Card(_email, _name);
}
private static Card testCard;
or separate method for it
public static void initialize(String name, String email)
{
_name= name;
_email = email;
testCard = new Card(_email, _name);
}
Also you should remove final modifiers if you want to initialize static in contructor.
I'm going back to OOP in java. Here I got problem with simple example:
class CreateString {
private String name;
public CreateString(String name) {
this.name = name;
}
String string = new String(name);//AAA
}
public class Main {
public static void main(String[] args) {
CreateString myName = new CreateString("tomjas");
}
}
I got NullPointerException from line denoted as "AAA". When I change the second line into
private String name="";
it's ok. What is wrong with that code? I thought that field is initialised as one could conclude from constructor. Any hints and pointers to documentation?
Your string variable is a class attribute. Therefore it will be initialized when your class instance is created. But at that time name is still null, as you only assign a value to name in the constructor. So you end up with a NullPointerException.
To fix it, move string = new String(name); into the constructor:
class CreateString {
private String name = null;
private String string = null;
public CreateString(String name) {
this.name = name;
string = new String(name);
}
}
As the constructor is only executed after all the attributes have been initialized, it doesn't matter where you put the line private String string;. You could also place it after the constructor (as you did), and it would still be fine.
All the fields are initialised before the constructor, as such when the line initialising string runs name is still null
class CreateString {
private String name; //<--runs first
public CreateString(String name) { //<--runs third
this.name = name;
}
String string = new String(name);//AAA <---runs second
}
You could move the string initialisation within the constructor to solve this
class CreateString {
private String name;
String String string;
public CreateString(String name) {
this.name = name;
string;= new String(name);//AAA
}
}
String string = new String(name);//AAA
That line is in initializer block.So the default value is null, Since you are using it before assigning some value. Move that line to constructor.
Since you dont have any base class defined for your class, the order of execution would be :
initialize member fields of this class.
run the constructor of this class.
Since while executing this
String string = new String(name);//AAA since it executes first.
the variable name is still null. That's why it throws NullPointerException
This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
Closed 7 years ago.
I was studying method overriding in Java when ai came across the this keyword. After searching much about this on the Internet and other sources, I concluded that thethis keyword is used when the name of an instance variables is same to the constructor function
parameters. Am I right or wrong?
this is an alias or a name for the current instance inside the instance. It is useful for disambiguating instance variables from locals (including parameters), but it can be used by itself to simply refer to member variables and methods, invoke other constructor overloads, or simply to refer to the instance. Some examples of applicable uses (not exhaustive):
class Foo
{
private int bar;
public Foo() {
this(42); // invoke parameterized constructor
}
public Foo(int bar) {
this.bar = bar; // disambiguate
}
public void frob() {
this.baz(); // used "just because"
}
private void baz() {
System.out.println("whatever");
}
}
this keyword can be used for (It cannot be used with static methods):
To get reference of an object through which that method is called within it(instance method).
To avoid field shadowed by a method or constructor parameter.
To invoke constructor of same class.
In case of method overridden, this is used to invoke method of current class.
To make reference to an inner class. e.g ClassName.this
To create an object of inner class e.g enclosingObjectReference.new EnclosedClass
You are right, but this is only a usage scenario, not a definition. The this keyword refers to the "current object". It is mostly used so that an object can pass itself as a parameter to a method of another object.
So, for example, if there is an object called Person, and an object called PersonSaver, and you invoke Person.SaveYourself(), then Person might just do the following: PersonSaver.Save( this );
Now, it just so happens that this can also be used to disambiguate between instance data and parameters to the constructor or to methods, if they happen to be identical.
this keyword have following uses
1.used to refer current class instance variable
class Student{
int id;
String name;
student(int id,String name){
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student s1 = new Student(111,"Karan");
Student s2 = new Student(222,"Aryan");
s1.display();
s2.display();
}
}
here parameter and instance variable are same that is why we are using this
2.used to invoke current class constructor
class Student{
int id;
String name;
Student (){System.out.println("default constructor is invoked");}
Student(int id,String name){
this ();//it is used to invoked current class constructor.
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student e1 = new Student(111,"karan");
Student e2 = new Student(222,"Aryan");
e1.display();
e2.display();
}
}
3.this keyword can be used to invoke current class method (implicitly)
4.this can be passed argument in the method call
5.this can be passed argument in the constructor call
6.this can also be used to return the current class instance
This refers current object. If you have class with variables int A and a method xyz part of the class has int A, just to differentiate which 'A' you are referring, you will use this.A. This is one example case only.
public class Test
{
int a;
public void testMethod(int a)
{
this.a = a;
//Here this.a is variable 'a' of this instance. parameter 'a' is parameter.
}
}
Generally the usage of 'this' is reserved for instance variables and methods, not class methods ...
"class methods cannot use the this keyword as there is no instance for
this to refer to..."
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Here's a trivial example ...
public class Person {
private String name;
private int age;
private double weight;
private String height;
private String gender;
private String race;
public void setName( String name ) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge( int age) {
this.age = age;
}
public int getAge(){
return this.age;
}
public void setWeight( double weight) {
this.weight = weight;
}
public double getWeight() {
return this.weight;
}
public void setHeight( String height ) {
this.height = height;
}
public String getHeight() {
return this.height;
}
public void setGender( String gender) {
this.gender = gender;
}
public String getGender() {
return this.gender;
}
public void setRace( String race) {
this.race = race;
}
public String getRace() {
return this.race;
}
public void displayPerson() {
System.out.println( "This persons name is :" + this.getName() );
System.out.println( "This persons age is :" + this.getAge() );
System.out.println( "This persons weight is :" + this.getWeight() );
System.out.println( "This persons height is :" + this.getHeight() );
System.out.println( "This persons Gender is :" + this.getGender() );
System.out.println( "This persons race is :" + this.getRace() );
}
}
And for an instance of a person ....
public class PersonTest {
public static void main( String... args ) {
Person me = new Person();
me.setName( "My Name" );
me.setAge( 42 );
me.setWeight( 185.00 );
me.setHeight( "6'0" );
me.setGender( "Male" );
me.setRace( "Caucasian" );
me.displayPerson();
}
}
In case of member variable and local variable name conflict, this key word can be used to refer member variable like,
public Loan(String type, double interest){
this.type = type;
this.interest = interest;
}
if you have knowladge about c,c++ or pointers, in that language this is a pointer that points object itself. In java everything is reference. So it is reference to itself in java. One of the needs of this keyword is that:
Think that this is your class
public class MyClass
{
public int myVar;
public int myMethod(int myVar)
{
this.myVar = myVar; // fields is set by parameter
}
}
If there is not this keyword you it is confused that this is paramter or class field.When you use this.myVar it refers field of this object.
I would like to modify your language. The this keyword is used when you need to use class global variable in the constructors.
public class demo{
String name;
public void setName(String name){
this.name = name; //This should be first statement of method.
}
}
this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
One more thing that should be in mind is that this keyword might be the first statement of your method.
This is used in java. We can use in inheritance & also use in method overloading & method overriding. Because the actual parameter or instance variable name has same name then we can used this keyword complsary . But some times this is not same as when we can not use this keyword complsary.....
Eg:- class super
{
int x;
super(int x)
{
this.x=x
}
}