public class Country implements ICountry {
int stability = 2;
}
Country poland = new Country(stability = 3);
What I'm trying to do is extend an interface(ICountry) with a new class("Country") that has a few default values. I want to know if it's possible to redefine some of those defaults when creating a new instance of the Country class. The last line of code in my example is what I currently have as my attempt to accomplish this, but my IDE is warning me that 'stability cannot be resolved to a variable'.
My questions is, is it possible to redefine some of an object's default values when instantiating a class without constructing a method?
I'm just starting to learn Java and Android programming on my own, so if you think I referred to something with the wrong terminology please correct me.
What you want is to define a constructor of Country that accepts a parameter and assigns it to a field, like so:
public class Country implements ICountry {
int stability = 2; // the default
public Country() {
// no parameters, no assignments
}
public Country(int stability) {
// declares parameter, assigns to field
this.stability = stability;
}
}
You can then create multiple instances of this class, like this:
Country unitedKingdom = new Country(); // 2 is the value of stability, taken from the default
Country poland = new Country(3); // 3 is the value of stability
The reason you need to have two constructors is that the version with no parameters (the "default", or "implicit" constructor) is generated if you haven't specified one, but once you specify a constructor, it won't be generated any more.
An alternate, and equivalent syntax for the default constructor could be:
public class Country implements ICountry {
int stability; // declare field, but don't assign a value here
public Country() {
this.stability = 2; // instead assign here, this is equivalent
}
}
Both this version and the previous version of the default constructor result in the same effect, but is generally a matter of preference.
There are languages that use the syntax you have shown, they're called "named parameters", but Java doesn't have them.
This is what overloaded constructors are for:
public Country(int stability)
{
this.stability=stability;
}
Related
In the below code snippet how can I set the value of a and b without using the setter method? Is it possible? Can I call the private constructor in the public constructor?
public class ABC {
private int a;
private int b;
public ABC() {
}
private ABC(int a, int b) {
this.a = a;
this.b = b;
}
}
ABC abc = new ABC();
You can use Java reflection, but this is considered to be bad practice and should be avoided. However, if you really need to:
ABC abc = new ABC();
Field abc_a = abc.getClass().getDeclaredField("a");
abc_a.setAccessible(true);
abc_a.set(abc, 20);
Explanation
Field abc_a = abc.getClass().getDeclaredField("a");
In java, there is a set of tools called Reflection, whose intended use is to allow for fields in classes to be dynamically set. A practical use of this is the GSON library, which reads JSON and automatically fills in the corresponding values in a class.
Every class has a Class object to assist with reflection, and every instance of an object has a method called getClass(). Calling this method will give you the Class object representing that class and using that, you can then invoke the getDeclaredField(fieldName) method which will return a Field object that allows you to do a variety of things to that field, one of which is setting the value.
abc_a.setAccessible(true);
Because the field being referenced to is private, this must be invoked to allow it to be accessed. If it was public, this step could be omitted.
abc_a.set(abc, 20);
This finally changes the value of the field a in the ABC class. The first parameter is the object you wish to change the value of, and the second parameter is the new value. Note that Field objects don't store class information, so if you wished to change the value of a different instance of ABC, you could use the same Field object and just change the first parameter.
If I understand you correctly, your actual question is
Can I call the private constructor in the public constructor?
and nothing really related to setters.
Yes, you can call one constructor from another. In your example code this would look like this:
public ABC() {
this(0, 0); // initialze a and b via the private constructor
}
I was able to pass a secret test with my code, which essentially test the code with certain input and expected output. I kept getting an assertion error which stated, expected<1> but was:<0> Until I changed the code from this:
public Gunner(){
this.gunpower = 1;
this.GunnerStrength = 1;
this.name = "Default Gunner";
}
to
public Gunner() {
this("Default Gunner", 1, 1);
}
To illustrate further and to give reference points, here are the codes which preceded the above code:
package ship;
public class Gunner {
private String name;
private int gunpower;
private int GunnerStrength;
private int maxGupower;
private int maxGunnerStrength;
private int currentGunpower;
private int currentGunnerStrength;
public Gunner(String l_name, int l_gunpower, int l_GunnerStrength) {
this.name = l_name;
this.currentGunpower = maxGunpower = l_gunpower;
this.currentGunnerstrength = maxGunnerStrength = l_GunnerStrength;
}
public Gunner(Gunner other) {
this.name = new String(other.name);
this.gunpower = new Integer(other.gunpower);
this.GunnerStrength = new Integer(other.GunnerStrength);
this.maxGunpower = new Integer(other.maxGunpower);
this.maxGunnerStrength = new Integer(other.maxGunnerStrength);
this.currentGunpower = new Integer(other.currentGunpower);
this.currentGunnerStrength = new Integer(other.currentGunnerStrength);
}
}
If someone could please explain the differences between the two codes above it would be much appreciated.
Your original Gunner() constructor attempted to duplicate the logic of the Gunner(String,int,int) constructor, although apparently (as you've passed whatever the "secret test" was), it failed to do so correctly since it filled in different fields: It initialized gunpower, GunnerStrength, and name; but the other constructor initializes name, currentGunpower, maxGunpower, currentGunnerStrength, and maxGunnerStrength. That's quite a different set of fields.
Your revised Gunner() constructor reuses the logic of the Gunner(String,int,int) constructor, rather than attempting to duplicate it. And so it fills in the fields that Gunner(String,int,int) fills in. Presumably the test expected those fields to be filled in.
In general, duplicating logic is a bad idea, because inevitably things change over time, so unless there are convincing arguments to the contrary, reusing rather than duplicating logic is the way to go.
Re your edit:
I kept getting an assertion error which stated, expected<1> but was:<0>
The default value of an int field is 0, so if you don't initialize or assign another value to the field, it will have the value 0. So presumably the unit test was checking the value of one of the fields your original Gunner() didn't fill in (currentGunpower, maxGunpower, currentGunnerStrength, or maxGunnerStrength) but your new Gunner() does fill in (via Gunner(String,int,int)).
Side note:
Difference between using these two default constructors?
There are no default constructors in your code. A default constructor is provided by the compiler if you don't define any constructors for the class. Since you do define constructors for the class, there is no default constructor.
Your Gunner() constructor is a constructor with no formal parameters, sometimes called a zero-params constructor or a zero-args constructor or a no-arg(s) constructor (Java uses "parameter" rather than "argument" to refer to the things you pass into methods and constructors, but they're also commonly called "arguments" informally, hence "args").
Ok I am trying to wrap my head around this:
Write an application that creates a class for the student object with the following attributes:
Student Number, Name, Address, Phone No., and Course.
Write a test program that sets and gets each attribute in the class.
The test program should also display all of the attributes in the class.
Using the student class and its attributes from the previous question, write an application (extend the previous program) that includes both a user-defined and default constructor.
Write a test program to demonstrate the use of both constructors.
This is a work-sheet from college, for some revision on Objects in Java.
The part that troubles me is the one where it asks to have both user-defined and default constructor?
I was under impression it was impossible to do it? Because if you don't provide a constructor yourself, JVM will provide one (default constructor?). But if you define any constructor, then default one becomes unavailable?
Is this just poorly worded task, or could it mean something else?
I'm pretty sure whoever created the work-sheet meant "No-arg constructor" instead of "Default constructor".
You can't technically create the Default constructor (since this is done for you by the compiler), but you can explicitly create the no-arg constructor (which functionally is the same).
So, yes, poorly worded task.
In java, when you don't explicitly specify a constructor, the compiler will add a "default" constructor: a constructor thar doesn't take parameters. If you specify a constructor, then the compiler doesn't add that constructor.
For instance, this code will compile fine:
class Student {
String name;
int age;
// ...
}
// ...
Student myself = new Student();
But this code wont compile:
class Student {
String name;
int age;
// ...
public Student(String name) {
this.name = name;
}
}
// ...
Student myself = new Student(); // compilation error: use new Student("Jhon Smith");
Because the default constructor is not available any more.
Java provide default constructor when you dont implement yourselve one. But when you create customized constructor you have to implement also default if you would like to use constructor with no arguments. Let's asume we have class A{} for java it will looks like that:
public class A{
public A(){//auto generated constructor
}
}
but if you provide an customized constructor auto generated constructor dissapear.
Default constructor is not created when programmer provides any constructor. But here I'm expecting that the author of this task understands "default" constructor as the one without any parameters.
Concluding you would have two constructors:
public class MyClass {
public MyClass () {
}
public MyClass (long studentNumber, String name, String address....) {
}
Above is correct, however, in OO terms, "default constructor" is a constructor that takes in no arguments. The other type of constructor is one where arguments are taken into the constructor to make things custom.
ie:
Student(){ //default constructor
number = 0;
name = "bob";
//etc etc
}
student(int nm, int nm, etc etc){ //parametrized constructor
number = nm;
name = nm;
//etc etc
}
According to Charatan & Kans, Java in Two semesters 3rd Edition, page 196:
Constructor just like any methods can be overloaded, meaning within a single class we can have 2 or more constructors, where one take 1 argument like:("studentName") and within the same class, another constructor might take 2 arguments ("studentName", " studentId"), yet another constructor still within the same class may have 3 arguments ("studentName", "studentId", " studentPhoneNumber").
This is Constructor Overloading. Here's an example:
public class student {
// attributes
private String studentName;
private int studentID;
private int studentPhoneNumber;
// constructor with one argument
public student (String studentNameIn) {
studentName = studentNameIn;
}
// constructor with 2 arguments
public student (String studentNameIn, int studentIdIn) {
studentName = studentNameIn;
studentID = studentIdIn;
}
// constructor with 3 arguments
public student (String studentNameIn, int studentIdIn, int studentPhoneNumberIn) {
studentName = studentNameIn;
studentID = studentIdIn;
studentPhoneNumber = studentPhoneNumberIn;
}
// default constructor REINSERTED no argument
public student () {}
// methods
}
The above is a clear example of constructor overloading. Now during the OBJECT creation, meaning when the student object is being created, it will be up to the programmer to utilise the constructor he/she chooses, with 0 arguments ( default that was REINSERTED) or with 1 argument again he/she may choose the constructor that contains 2 arguments etc. Its a matter of choice and requirement of user.
No superclass or multiple class is needed as constructor can be overloaded as demonstrated above.
I have noticed a thing that a constructor and a simple method of a class do the same work. what is the exact reason to create a construct of a class? If i create MyClass(){} constructor and MyClassMethod(){} method it will do the same work as I write the body part of those method and constructor. So what is the need of construct? Does it have any special use ?
A constructor and a method are two different things. The fact that you can write the same or similar code inside them is irrelevant.
When a new object is created a constructor is called. If you don't specify one the compiler will create a default one for you. This is the place where initializaton of the object's fields takes place and memory is allocated for the object. This is a concept that all object-oriented languages have. A new object must be initialized somehow. Memory needs to be allocated. In Java you don't manage the memory yourself (at least not directly anyway) so this is the purpose of the constructor. Note that since a constructor is always executed, this behaviour is enforced as soon as you call e.g. Person p = new Person();.
Now since a constructor is always being called, you have an option here: do you let the default constructor execute or do you create one yourself? Perhaps there are fields that need to be initialized in a way other than their default values. Or perhaps you need to not allow creating an object without providing some values. If you define a constructor yourself, the compiler does not create a default one for you. So if I have public Person(String firstName, String lastName) {} then I have created a specific rule that is again enforced by the system: a new object of class Person cannot be created unless you give a first name and last name:
Person p = new Person(); // this would give a compile error
Person p = new Person("John", "Smith"); // this is the only way to create an object now
Using a method you cannot enforce this. The programmer using your class might call your method or not. The constructor is a part of the lifecycle of the object. Methods define the behaviour of the object
Some points :
1) Constructors are the only way to set final instance variables .
public class SomeType {
final int x ;
SomeType(int y){
x=y;
}
}
2) A class with private constructor cannot be sub classed.
3) If your class is a subclass and the base class doesn't have a default constructor , then you need a constructor in your class to call the super class constructor.
One of the benefits of using a constructor over a method is that you can be assured the constructor was called and the work within the constructor was performed.
The language specifies that to construct an object a constructor must be called. So if you use a custom method to establish the initial state of your object, you will need to call the default constructor first. Why make two method calls when you can perform the work in one call the constructor and be assured the object has been properly initialized?
public class Test(){
private Integer x;
public Test(){
}
public Test(Integer x){
this.x = x;
}
public void setX(Integer x){
this.x = x;
}
public void doSomethingWithX(){
this.x.toString();
}
}
Test test = new Test(8);
test.doSomethingWithX(); //I know x has been declared and assigned
Test test = new Test();
test.doSomethingWithX(); //X has not been assigned results in NPE
If you create a new Object of MyClass it will automatically call the constructor - you can initialize all members within it, and be sure that this object´s members are all initialized.
Generally:
A constructor is always called once when you create a new Object of this class, and you can´t call it manually.
And don´t do "real" work in a constructor, as it will slow down the creation of objects of this class - only initialize your class/members there.
You can also use different constructors, depending on your needs - but if you create a constructor, there is no more default constructor!
Example:
public MyClass {
int score;
public MyClass(int sc) { // already know the score
score = sc;
}
public MyClass() { // don´t know the score yet
score = 1;
}
public void addScore() {
score += 5; // i know for sure that score is not zero
}
}
Essentially a constructor is just a special method that implicitly returns an object of its containing type. You should generally use constructors for creating objects - this is what people expect to see.
However, there is a useful idiom called the factory method (more info at this link) which is essentially using a static method to construct an object, the key advantages being
You can give a factory method a more descriptive name (whereas of course a standard constructor has to be named after the containing class).
They don't have to return an object, giving more flexibility.
They can return a sub-types of the class.
You can set final fields without initializer in a constructor. This helps to build immutable instances:
class Number extends Expr {
private final int n;
public Number(int n) {
this.n = n;
}
public int getValue() {
return this.n;
}
}
So after a constructor like this, you can rely on the fact that the instance is initialized completely (and in this case, it's values are immutable/constant).
Constructor is not like simple methods. It is called every time when the object of that particular class is created. You don't need to call it explicitly.
There are somethings that we need to do immediately when the object is created, for instance when you create a GUI kind of thing you want to set many properties on the time of creation like size of window etc.
Another benefit of constructor is security of class. You cannot create a object unless you know the right perimeters of constructor.
More details:http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
A constructor is a special method of a class or structure in object-oriented programming that initializes an object of that type.
Some points :
1. A constructor eliminates placing the default values.
2. A constructor eliminates calling the normal method implicitly.
These are the benefits of constructors.
Automatic initialization of objects at the time of their declaration.
Multiple ways to initialize objects according to the number of
arguments passes while declaration.
The objects of child class can be initialised by the constructors of base class.
So, I have willfully kept myself a Java n00b until recently, and my first real exposure brought about a minor shock: Java does not have C# style properties!
Ok, I can live with that. However, I can also swear that I have seen property getter/setter code in Java in one codebase, but I cannot remember where. How was that achieved? Is there a language extension for that? Is it related to NetBeans or something?
There is a "standard" pattern for getters and setters in Java, called Bean properties. Basically any method starting with get, taking no arguments and returning a value, is a property getter for a property named as the rest of the method name (with a lowercased start letter). Likewise set creates a setter of a void method with a single argument.
For example:
// Getter for "awesomeString"
public String getAwesomeString() {
return awesomeString;
}
// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
this.awesomeString = awesomeString;
}
Most Java IDEs will generate these methods for you if you ask them (in Eclipse it's as simple as moving the cursor to a field and hitting Ctrl-1, then selecting the option from the list).
For what it's worth, for readability you can actually use is and has in place of get for boolean-type properties too, as in:
public boolean isAwesome();
public boolean hasAwesomeStuff();
I am surprised that no one mentioned project lombok
Yes, currently there are no properties in java. There are some other missing features as well.
But luckily we have project lombok that is trying to improve the situation. It is also getting more and more popular every day.
So, if you're using lombok:
#Getter #Setter int awesomeInteger = 5;
This code is going to generate getAwesomeInteger and setAwesomeInteger as well. So it is quite similar to C# auto-implemented properties.
You can get more info about lombok getters and setters here.
You should definitely check out other features as well.
My favorites are:
val
NoArgsConstructor, RequiredArgsConstructor, AllArgsConstructor
Logs!
Lombok is well-integrated with IDEs, so it is going to show generated methods like if they existed (suggestions, class contents, go to declaration and refactoring).
The only problem with lombok is that other programmers might not know about it. You can always delombok the code but that is rather a workaround than a solution.
"Java Property Support" was proposed for Java 7, but did not make it into the language.
See http://tech.puredanger.com/java7#property for more links and info, if interested.
The bean convention is to write code like this:
private int foo;
public int getFoo() {
return foo;
}
public void setFoo(int newFoo) {
foo = newFoo;
}
In some of the other languages on the JVM, e.g., Groovy, you get overridable properties similar to C#, e.g.,
int foo
which is accessed with a simple .foo and leverages default getFoo and setFoo implementations that you can override as necessary.
public class Animal {
#Getter #Setter private String name;
#Getter #Setter private String gender;
#Getter #Setter private String species;
}
This is something like C# properties. It's http://projectlombok.org/
You may not need for "get" and "set" prefixes, to make it look more like properties, you may do it like this:
public class Person {
private String firstName = "";
private Integer age = 0;
public String firstName() { return firstName; } // getter
public void firstName(String val) { firstName = val; } // setter
public Integer age() { return age; } // getter
public void age(Integer val) { age = val; } //setter
public static void main(String[] args) {
Person p = new Person();
//set
p.firstName("Lemuel");
p.age(40);
//get
System.out.println(String.format("I'm %s, %d yearsold",
p.firstName(),
p.age());
}
}
Most IDEs for Java will automatically generate getter and setter code for you if you want them to. There are a number of different conventions, and an IDE like Eclipse will allow you to choose which one you want to use, and even let you define your own.
Eclipse even includes automated refactoring that will allow you to wrap a property up in a getter and setter and it will modify all the code that accesses the property directly, to make it use the getter and/or setter.
Of course, Eclipse can only modify code that it knows about - any external dependencies you have could be broken by such a refactoring.
My Java experience is not that high either, so anyone feel free to correct me. But AFAIK, the general convention is to write two methods like so:
public string getMyString() {
// return it here
}
public void setMyString(string myString) {
// set it here
}
From Jeffrey Richter's book CLR via C#: (I think these might be the reasons why properties are still not added in JAVA)
A property method may throw an exception; field access never throws an exception.
A property cannot be passed as an out or ref parameter to a method; a field can.
A property method can take a long time to execute; field access always completes
immediately. A common reason to use properties is to perform thread synchronization,
which can stop the thread forever, and therefore, a property should not be
used if thread synchronization is required. In that situation, a method is preferred.
Also, if your class can be accessed remotely (for example, your class is derived from
System.MarshalByRefObject), calling the property method will be very slow, and
therefore, a method is preferred to a property. In my opinion, classes derived from
MarshalByRefObject should never use properties.
If called multiple times in a row, a property method may return a different value each
time; a field returns the same value each time. The System.DateTime class has a readonly
Now property that returns the current date and time. Each time you query this
property, it will return a different value. This is a mistake, and Microsoft wishes that
they could fix the class by making Now a method instead of a property. Environment’s
TickCount property is another example of this mistake.
A property method may cause observable side effects; field access never does. In other
words, a user of a type should be able to set various properties defined by a type in
any order he or she chooses without noticing any different behavior in the type.
A property method may require additional memory or return a reference to something
that is not actually part of the object’s state, so modifying the returned object has no
effect on the original object; querying a field always returns a reference to an object
that is guaranteed to be part of the original object’s state. Working with a property
that returns a copy can be very confusing to developers, and this characteristic is frequently
not documented.
If you're using eclipse then it has the capabilities to auto generate the getter and setter method for the internal attributes, it can be a usefull and timesaving tool.
I'm just releasing Java 5/6 annotations and an annotation processor to help this.
Check out http://code.google.com/p/javadude/wiki/Annotations
The documentation is a bit light right now, but the quickref should get the idea across.
Basically it generates a superclass with the getters/setters (and many other code generation options).
A sample class might look like
#Bean(properties = {
#Property(name="name", bound=true),
#Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}
There are many more samples available, and there are no runtime dependencies in the generated code.
Send me an email if you try it out and find it useful!
-- Scott
There is no property keyword in java (like you could find it in C#) the nearest way to have 1 word getter/setter is to do like in C++:
public class MyClass
{
private int aMyAttribute;
public MyClass()
{
this.aMyAttribute = 0;
}
public void mMyAttribute(int pMyAttributeParameter)
{
this.aMyAttribute = pMyAttributeParameter;
}
public int mMyAttribute()
{
return this.aMyAttribute;
}
}
//usage :
int vIndex = 1;
MyClass vClass = new MyClass();
vClass.mMyAttribute(vIndex);
vIndex = 0;
vIndex = vClass.mMyAttribute();
// vIndex == 1
As previously mentioned for eclipse, integrated development environment (IDE) often can create accessor methods automatically.
You can also do it using NetBeans.
To create accessor methods for your class, open a class file, then Right-click anywhere in the source code editor and choose the menu command Refactor, Encapsulate Fields.
A dialog opens. Click Select All, then click Refactor.
Voilà,
Good luck,
For me the problem is two fold:
All these extra methods {get*/set*} cluttering up the class code.
NOT being able to treat them like properties:
public class Test {
private String _testField;
public String testProperty {
get {
return _testField;
}
set {
_testField = value;
}
}
}
public class TestUser {
private Test test;
public TestUser() {
test = new Test();
test.testProperty = "Just something to store";
System.out.printLn(test.testProperty);
}
}
This is the sort of easy assignment I would like to get back to using. NOT having to use 'method' calling syntax. Can anyone provide some answers as to what happened to Java?
I think that the issue is also about the unnecessary clutter in the code, and not the 'difficulty' of creating the setters/getters. I consider them as ugly-code. I like what C# has. I don't understand the resistance to adding that capability to Java.
My current solution is to use 'public' members when protection is not required:
public class IntReturn {
public int val;
}
public class StringReturn {
public String val;
}
These would be used to return value from say a Lambda:
StringReturn sRtn = new StringReturn()
if(add(2, 3, sRtn)){
System.out.println("Value greater than zero");
}
public boolean add(final int a, final int b, final StringReturn sRtn){
int rtn = a + b;
sRtn.val = "" + rtn;
return rtn > 0; // Just something to use the return for.
}
I also really don't like using a method call to set or get an internal value from a class.
If your information is being transferred as 'immutable', then the new Java record could be a solution. However, it still uses the setter/getter methodology, just without the set/get prefixes.