My question is: why must we pass global variables(members, names) to an object if we want to use it. Isn't a global variable declared for all objects to have access to it?
public class Family {
int members;
String names;
public Family(int members, string names) {
this.members = members;
this.names = names;
}
}
How else do you initialize the variables in an object?
Let me try to explain you this way, Suppose what you were asking was possible then, if we were to create 100 different family objects and if the variables were supposed to have different data, how will that be possible? Because changing a global field would affect all the objects right.
So basically when you create the object you either initialize the fields using a constructor as you have done in the sample or you can use a no args constructor and set the values after the object is created using "Setters".
For more understanding on initialization.
Refer: https://www.google.com/amp/s/www.javaworld.com/article/3040564/java-101-class-and-object-initialization-in-java.amp.html
Hope this helps.
The piece of code mentioned above is actually a class definition . Class is just a template which has member variables and member functions associated with it.Now Object is an instance of the class which has got some values for the variables which is generally get and set using getters and setters respectively.Other operations can be performed by member functions.Constructors are used to initialize the object.
public Family(int members, string names) {
this.members = members;
this.names = names;
}
is a paramaterized constructor used to initialize the object with the parameters passed .This will obviously be useful while creating more than 1 objects of a class as each object will have different values associated with it.To be more clear:
public class Family {
int members;//member variable scope-class level
String names;//member variable scope-class level
public Family(int members, String names) {//int members,string names are parameters scope-constructor ,we can give any name to these two variables like int param_member,String param_names
this.members = members;//LHS specifies the variable- member of the class and RHS specifies variable passed as parameter
this.names = names; //LHS specifies the variable-names of the class and RHS specifies variable passed as parameter
}
}
Related
The following class has an array of integer
public class customers {
public static int ID[];
public customers(int ID[]) {
ID = new int[10];
ID[0] = 00245;
ID[1] = 76644;
// more
}
//getters and setters
The subclass is defined as follow
public class songs extends customers {
//bunch of fields
The issue rises when within my array of objects. To create it, the following constructor was needed
public songs(int ID, // bunch of fields {
super(ID[0]);
this.ID = ID[];
// bunch of fields
Here, the super() method throws me back an error, that int[] in customers cannot be defined as a simple int.
Same goes when populating my array :
arraylist.add(new songs(ID[0], ...)); // didnt paste other variables
ID[0] is considered a simple int and not a int[].
While I understand the error itself, I don't know what causes it nor how to make java use my array of customers within the arrayList of Object defined in songs.
Thanks in advance !
If you want to send an array through subclass constructor you must first have a non-static (instance) array field in your super class, like this:
private int[] ids;
Be noticed that in java the fields are usually defined in camel case format.
Also you have a syntax error in this line:
super(ID[0])
You are referencing the int parameter defined in songs constructor as if an array, that is not correct.
Your call on super(ID[0]); is wrong: it calls the constructor of your members class, sending to it an int rather than an int[] as specified by your constructor. Moreover, I believe this.ID = ID[]; is wrong as well: "ID[]" in this context doesn't represent anything.
Also, as mentioned, static is probably not the good approach: it means that all Objects of type "Members" will share the same one-and-unique attribute "ID[]"!
More code would help. Especially about your songs, and the "arraylist" you're talking about.
I'm new to coding and I've faced this problem recently: I'm working on a class which has various fields, and I want to insure each instance of the class has a unique value for a certain field using static variables. for example, consider this class:
public class NetworkNode {
private String NodeName;
private int NodeNumber;
private boolean NodeAttraction;
....
}
in the code above, I want to insure each object created from the class NetworkNode to have a unique and different NodeNumber or in other words, no two NetworkNode objects should have the same NodeNumber field.
what are the ways to do this? thanks.
You could automatically assign a different NodeNumber to each instance if you don't care about the actual value as long as it's unique. Using static variables you could create a private static counter nextNodeNumber in your class NetworkNode:
private static int nextNodeNumber = 0;
In your constructor you could then do
public NetworkNode() {
this.NodeNumber = nextNodeNumber;
++nextNodeNumber;
...
}
This way you just have to ensure, that there is no other way to set/change NodeNumber or nextNodeNumber.
If you are using multiple Threads you would have to secure access to nextNodeNumber to prevent asynchronous access.
1 put a
static Set<String> myuniquevalues ... (for example) for each of your fields
2 in your constructor
public NetworkNode (String value1 ...)
{... check if value1 exists in myuniquevalues , and throw exceptions }
3 if your objects are deleted, you must manage it also ...
Alternative: concentrate creation of your objects in a factory, and manage unicity there.
I recommend you to do some reading about variables and what static means. To make it short, a static variable exists only "once" in your program.
For example, if you create a game, you want the variable score to be static since there will only be one instance of this variable.
In order to have each NetworkNode to have a unique and different NodeNumber, you have to construct the object like this:
public NetworkNode(String NodeName, int NodeNumber, boolean NodeAttraction){
this.NodeName = NodeName;
this.NodeNumber = NodeNumber;
this.NodeAttraction = NodeAttraction;
}
See, here, each NetworkNode will have a different value for each of the variables passed as parameters.
You will then just need to create the object in your main function or whatever like this for example:
NetworkNode myNode = new NetworkNode("node1", 0, true);
Hope it helps,
I have a Model class defined in my project. and as usual it has some private variables and public getters and setters
public class Person{
private ArrayList<String> mark;
public void setMark(ArrayList<String> mark){
this.mark = mark;
}
public void getMark(){
return this.mark;
}
}
Suppose in some other class I am using this Model like
Person person = new Person();
ArrayList<String> mark = new ArrayList();
mark.add("10");
mark.add("15");
mark.add("18");
person.setMark();
then the private variable of person holds the value "my name", the I am accessing the variable using public getter of the class like
ArrayList<String> localMark = person.getMark()
so as per my knowledge person.getMark() returns the reference of private variable name, so if I modify the local variable 'localMark', then it will effect the private variable of Person class, so there it breaks the private property of the variable
ex:
ArrayList<String> localMark = person.getMark();
System.out.println(localMark.get(0)); // will be "10"
localMark.set(0,"25") // person.mark will be changed
System.out.println(person.getMark().get(0)); //will be printing "25"
most of the developers following the same design pattern I guess, but what is the correct way to create Models
EDIT
As per the comment of vinod I checked, and Strings it passes value but not reference but for ArrayList... it returns reference.
You have a reference (name) to an object instance (the value of name). As the reference is private, you're in full control of it.
When you return a reference, you in fact return it 'by value', meaning that a copy of the reference is returned. Both references point to the same value (the String instance)).
An outside caller obtaining the reference can assign a new value, but your model's own reference is unaffected by that and still points to the value.
It's like a dog (object) on a leash (reference).
When you return a reference you're returning a new leash onto the same dog.
The owner of the new reference can modify your dog (pet it, shave it, whatever) when the dog is mutable (which Strings are not, so it cannot be modified)
...or he can attach a new dog to his leash
...but he can never (reflection aside) attach YOUR leach to another dog.
If the instance being exposed by call to get() is mutable, then whatever changes you make in some other place will be reflected in the instance everywhere it is used.
Example :
methodX classA -
List<String> locaNamesList = person.getNamesList();
locaNamesList.clear();
Somewhere else
methodY classB -
List<String> locaNamesList = person.getNamesList(); // note the same person instance should be used.
//locaNamesList will be empty here
Just re-assigning the reference won' change anything.
List<String> locaNamesList = person.getNamesList();
locaNamesList = null; // won't change the actual list. You are setting local field locaNamesList to null and not the actual instance.
You have to use defensive-copies of mutable instances and pass them around if you don't want the original instance to be changed by external players (provided you can't make the instance itself immutable)
I have a requirement to check if the member variables of a class are there in a list or not. For this, I need to get all the variables of a class dynamically (if possible as a list). Is there a method for that in java?
Thanks,
KD
This is the concept of Reflection. You should be able to do something like the following (untested) code snippet:
/**
* #return {#code true} if all of the values of the fields in {#code obj} are
* contained in the set of {#code values}; {#code false} otherwise.
*/
public boolean containsAllValues(HashSet<Object> values, MyClass obj) {
Field[] fields = MyClass.class.getFields();
for (Field field : fields) {
Object fieldValue = field.get(obj);
if (values.contains(fieldValue)) {
return false;
}
}
return true;
}
You may get all of the field names (and their values) by calling Class#getFields()
Example: Consider the class below
public class Test{
public int x, y, z;
}
Test.class.getFields() will return the fields x,y,z, in which you could get their name through Field#getName() and get their value by calling the appropriate get method. In the Test class above, you could do something like this:
Test instance = new Test();
instance.x = 50;
int xValue = Test.class.getField("x").getInt(instance);
The value of xValue would be 50.
For a better demonstration of how it works, please see this.
You're talking about reflection.
Have a look at Class.getFields():
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html
See also:
http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/
There are quite a lot of fishhooks with reflection. Property-based access -- bean properties, of the form getX()/setX() or isX()/setX() -- may be a little better in helping you avoid unstable implementation internal of the class.
You can use the getFields() method, that will return a Field array: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getFields()
And then the getName() method for each element in the Field[] to get the name: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Field.html#getName().
Most answers recommend Class.getFields() but as the JavaDoc states, it will only return the public fields:
Returns an array containing Field objects reflecting all the
accessible public fields of the class or interface represented by this
Class object.
I rarely make my class fields public and rather make them private with getters and setters. To get the list of all fields (including private, protected and package private) you need to use Class.getDeclaredFields():
Returns an array of Field objects reflecting all the fields declared
by the class or interface represented by this Class object. This
includes public, protected, default (package) access, and private
fields, but excludes inherited fields.
Note that unlike Class.getFields(), Class.getDeclaredFields() will not returned the inherited fields. To get those you need to loop through the class hierarchy (loop over Class.getSuperclass() until you reach Object.class). Private fields names could be repeated in parent classes.
My goal is to make a Java object immutable. I have a class Student. I coded it in the following way to achieve immutability:
public final class Student {
private String name;
private String age;
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
My question is, what is the best way to achieve immutability for the Student class?
Your class is not immutable strictly speaking, it is only effectively immutable. To make it immutable, you need to use final:
private final String name;
private final String age;
Although the difference might seem subtle, it can make a significant difference in a multi-threaded context. An immutable class is inherently thread-safe, an effectively immutable class is thread safe only if it is safely published.
There are few things that you must consider for making an immutable class:
Make your class final - You already have
Make all the fields private and final - Make appropriate changes in your code
Don't provide any methods that change the state of your instance
If you have mutable fields in your class, like List, or Date, making them final won't suffice. You should return a defensive copy from their getters, so that their state isn't mutated by calling methods.
For the 4th point, say you have a Date field in your class, then the getter for that field should look like:
public Date getDate() {
return new Date(this.date.getTime());
}
Making a defensive copy can become a headache, when your mutable field itself comprises of some mutable field, and that in turn can contain some other mutable field. In that case, you would need to make copy of each of them iteratively. We name this iterative copy of mutable fields as Deep Copy.
Implementing deep copy by yourself may be cumbersome. But,keeping that issue apart, you should consider your class design again, once you see yourself falling into such requirement of making deep defensive copy.
How do you make a mutable object immutable?
Declare the class as final so it can’t be extended.
Make all fields private so that direct access is not allowed.
Don’t provide setter methods for variables
Make all mutable fields final so that it’s value can be assigned only once.
Initialize all the fields via a constructor performing deep copy.
Perform cloning of objects in the getter methods to return a copy rather than returning the actual object reference.
source
Why do we create immutable objects?
Immutable objects are simply objects whose state (the object's data) cannot change after construction.
Security: store sensitive pieces of information like usernames, passwords, connection URLs, network connections etc.
are simple to construct, test, and use
are automatically thread-safe and have no synchronization issues
don't need a copy constructor
don't need an implementation of clone
allow hashCode to use lazy initialization, and to cache its return value
don't need to be copied defensively when used as a field
make good Map keys and Set elements (these objects must not change state while in the collection)
have their class invariant established once upon construction, and it never needs to be checked again
always have "failure atomicity" (a term used by Joshua Bloch): if an immutable object throws an exception, it's never left in an undesirable or indeterminate state
Source
In Java, Strings are immutable, which provides, such as caching, security, easy reuse without replication, etc.
Source
With final keyword:
private final String name;
private final String age;
Making variables private and no setter methods will work for primitive data types. If my class has any collection of objects?
To making any class immutable with collection object?
Write your own collection object with extends collection class and follow the private variables and no setter methods. or return clone object of your collection object.
public final class Student {
private StudentList names;//Which is extended from arraylist
public Student() {
names = DAO.getNamesList()//Which will return All Student names from Database its upto you how you want to implement.
}
public StudentList getStudentList(){
return names;//you need to implement your own methods in StudentList class to iterate your arraylist; or you can return Enumeration object.
}
public Enumeration getStudentNamesIterator(
Enumeration e = Collections.enumeration(names);
return e;
}
public class StudentList extends ArrayList {
}
This is fine but I would make the fields final as well.
Also I would make the age an int or double rather than a String.
Expanding on the answer a bit.
final is not the same as Immutable but you can use final to make certain things immutable if you use it in certain ways.
Certain types are immutable, in that they represent unchanging values rather than objects of changeable state. Strings, numbers, etc are immutable. At the end, usually our objects boil down to data structures eventually referencing immutable values, but we change the data structures by assigning new values to the same field names.
So to make something truly immutable you need to make sure that final is used all the way down, until you reach every field reaching every value at the base of your composition tree. Otherwise something could change out from under your the object and it isn't really fully immutable.
Your example is already immutable object, because fields in Student class can only set on instance initialization.
To make object immutable, You must do these steps:
Don't use any methods, which can change fields of your class. For example don't use Setters.
Avoid to use public non-final fields. If your fields is public then you must declare them as final and initialize them in constructor or directly in the declaration line.
It is too late to answer but may be it help other peoples who have this question.
State of immutable object can not be modified after construction, any modification should result in new immutable object.
All fields of Immutable class should be final.
Object must be properly constructed i.e. object reference must not leak during construction process.
Object should be final in order to restrict sub-class for altering immutability of parent class.
I think this link help more
Read more: http://javarevisited.blogspot.com/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html#ixzz40VDQDDL1
It already is immutable -- you can't change the contents once you initialize it, since you haven't made setters. You might add final keywords to the variables.
Making all variables as final and when setting some field, making it return the reference to the new Student object with the newly set value like in String.
You can just follow guidelines shown in this example (first result in google):
http://www.javapractices.com/topic/TopicAction.do?Id=29
Here are few rules, which helps to make a class immutable in Java :
1. State of immutable object can not be modified after construction, any modification should result in new immutable object.
2. All fields of Immutable class should be final.
3. Object must be properly constructed i.e. object reference must not leak during construction process.
4. Object should be final in order to restrict sub-class for altering immutability of parent class.
Example:
public final class Contacts {
private final String name;
private final String mobile;
public Contacts(String name, String mobile) {
this.name = name;
this.mobile = mobile;
}
public String getName(){
return name;
}
public String getMobile(){
return mobile;
}
}
Refer this link : http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html
According to Strategy for Defining Immutable Objects
Don't provide "setter" methods — methods that modify fields or
objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
a. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
a. Don't provide methods that modify the mutable objects.
b. Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
Java SE 16
You can use JEP 395: Records feature, introduced as part of Java SE 16, to create an immutable class in a succinct manner.
If you have already gone through the above link, you must have figured out that you can do it simply as
record Student(String name, String age) { }
What you get in turn are:
A final class Student.
A canonical constructor whose signature is the same as the header, Student(String name, String age).
private final fields, name and age and their corresponding public accessor method with the same name and return type.
Automatically created equals, hashCode and toString methods.
Demo:
Student.java
record Student(String name, String age) { }
Main.java
class Main{
public static void main(String[] args) {
Student s1 = new Student("Bharat", "10 Years");
Student s2 = new Student("Arvind", "10 Years");
System.out.println(s1);
System.out.println(s1.equals(s2));
System.out.println(s1.age().equals(s2.age()));
}
}
Output:
Student[name=Bharat, age=10 Years]
false
true
Make the class or variable as final that's more than enough
Public final class constants
{
private final String name;
private final String mobile;
// code
}