I wonder if the following implementation is correct or if there is something simpler to do. My idea is to call the method to initialize the static attribute only once. Since the initialization method needs the id attribute, I guess I have to do it in the constructor.
public class A {
private int id;
private static Point2D[] myArray = new Point2D[10];
public A(int id) {
this.id = id;
if (myArray[0] == null) { // I want the array to be initialized only once.
initArray(id);
}
}
private static void initArray(int id) {
for (int i = 0; i < myArray.length; i++) {
myArray[i] = new Point2D(id, id);
}
}
}
Your code looks good to me. As you have made static members private, so only way it can be set in constructor or in any other method by passing the variable and having a check condition. Static initializer won't work as it runs before constructor, and you won't get ID till then.
The object myArray is actually initialized only once, that is when you call the new operator, and you can't push values in this object because the variable id is not final (and static).
Probably ask to yourself if you really need this class and which are the responsibilities of it.
Related
I came across this kind of example and had difficulty to understand it's actuall purpose:
class YieldDemo extends Thread
{
static boolean finished = false;
static int sum = 0;
public static void main (String [] args)
{
new YieldDemo ().start ();
for (int i = 1; i <= 50000; i++)
{
sum++;
if (args.length == 0)
Thread.yield ();
}
finished = true;
}
public void run ()
{
while (!finished)
System.out.println ("sum = " + sum);
}
}
I've never seen this kind of implementation - why initiating a the new class inside the same class object and not outside the class? is there any particular reason?
In fact you are outside of the class object itself. The main method is a static method, thus it has no dependency on any object instance.
You could also move the main method to any other java file. In general it will also work. However, you need to put static methods in some file. As every java file needs to be a class, you may put the method in the class it works for. For example, the class Math in java is a pure utility class, it has no non-static method.
However, if you create something like this:
public final class Value {
private final int mValue;
public Value(int value) {
mValue = value;
}
public int getValue() {
return mValue;
}
public Value increase() {
return new Value(mValue + 1);
}
}
It can actually make sense if you want Value to be immutable (not change its internal value). So, calling increase() does not increase the value itself but creates a new instance of this object, with an increased value.
I have an object, obj, of type MyObject, that I declare an instance of.
MyObject obj;
However, I don't initialize it. MyObject's Class looks something like:
public class MyObject {
public String i;
public String j;
public MyObject(String i) {
i = this.i;
}
}
So now, I want to set the value of j. So I say:
obj.j = "Hello";
Can I do this without having initialized obj? i.e. without saying:
obj = new MyObject("My i");
Will this object be null if I were to check the value of it, if I don't initialize it, or is setting a field within it enough to make it not null?
Thanks!
No, you cannot do that. You will have to create a new instance of MyObject if you want to access its fields.
Unless you make the fields static, ofcourse.
Do note that having your fields public violates encapsulation. You should make them private (or protected, if it's appropriate) and use getters and setters to provide access.
Sidenote:
public MyObject(String i) {
i = this.i;
}
This will not do what you want.
You have to assign the parameter i to the field variable i, not the other way around.
public MyObject(String i) {
this.i = i;
}
This question already has answers here:
Why isn't calling a static method by way of an instance an error for the Java compiler?
(12 answers)
Closed 9 years ago.
I'm trying to fully understand how does "this" work. In my previous post I understood why we use the "this" keyword.
My understanding of static is that the class has one copy of that member. "this" is used to represent the current object. For all objects, the static member variable is same, then why does "this" works on static member variables?
code:
public class OuterInnerClassExample
{
public static void main(String[] args)
{
OuterClass outClassObj = new OuterClass(10);
outClassObj.setInt(11);
outClassObj.setInt(12);
System.out.println("Total Count: " + outClassObj.getCount() );
}
}
class OuterClass
{
private int test;
private static int count; // total sum of how many new objects are created & the times all of them have been changed
public OuterClass(int test)
{
this.test = test;
// count += 1; // preferred as count is static
this.count += 1; // why does this work
}
public int getInt()
{
return this.test;
}
public int getCount()
{
return this.count;
}
public void setInt(int test)
{
this.test = test;
// count += 1; // preferred as count is static
this.count += 1; // why does this work
}
class SomeClass
{
private OuterClass outClassObj;
public SomeClass(int var)
{
outClassObj = new OuterClass(var);
}
public int getVar()
{
return this.outClassObj.getInt();
}
public int getCount()
{
return this.outClassObj.getCount();
}
public void setVar(int var)
{
// OuterClass.this.test = var; // can do this
outClassObj.setInt(var); // preferred
// OuterClass.count += var; // should do this
OuterClass.this.count += var; // why does this work
}
}
}
Also, in the setVar method, we can use ClassName.this to manipulate the objects value, but I think it is better to use a setter as it is much clearer. Is there any advantage of using "this" here that I am missing out?
Please post code to show examples of what you are trying to explain.
The underlying reason is that you can call a static member/method either on the class name MyClass.someStaticField or on an instance of the class new MyClass().someStaticField.
So as long as this is "available", MyClass.someStaticField is equivalent to this.someStaticField.
In your case, you always call this from instance methods so it does exist and the statement compile.
And finally, inner classes (non-static nested classes) contain a reference to their enclosing class, which allows OuterClass.this.count to compile too.
Whenever you do (some expression).staticMember, the compiler only uses the compile-time type of the expression to determine what static member to access. It doesn't matter what the expression is or what value it evaluates to.
It could be ((MyClass)null).someStaticField and it would not make a difference.
Right now I have two .java files.
The Main.java:
public class Main {
static int integer = 15;
NeedInteger need = new NeedInteger();
}
and the NeedInteger.java
public class NeedInteger {
System.out.println(integer);
}
This is of course very simplified, but is there any way I can accomplish this?
As many have answered, the correct method is to pass the value in to the constructor of the new class.
If for some reason you cannot do that, then you can use a public static accessor method in Main to access the value (this would be slightly better than just making the field public).
E.g.
public class Main
{
private static int integer = 15;
public static int getInteger()
{
return integer;
}
}
public class NeedInteger
{
public NeedInteger()
{
int integer = Main.getInteger();
}
}
Add a constructor to NeedInteger (and optionally a member if you need to also store it):
public class NeedInteger {
private int integer;
public NeedInteger(int integer) {
this.integer = integer;
System.out.println(integer);
}
}
Then pass your value when you create the instance:
public class Main {
static int integer = 15;
NeedInteger need = new NeedInteger(integer);
}
You would have to do some bad juju moves (like using a global variable) or pass it to the constructor.
NOTE: your
public class NeedInteger {
System.out.println(integer);
}
has no method in it. I would recommend all this to be rewritten as such:
public Class NeedInteger {
NeedInteger(int integer) {
System.out.println(integer);
}
}
If you really want the work to be done on construction.
EDIT: From your comment above.
Instead, have the class structured so:
public Class NeedStringArray {
NeedStringArray(String[][][] stringArr) {
//work with String array here
}
}
That has no real additional overhead, since the actual array will not be passed, but only a reference to it. You WILL likely want to set the array to be final or something, to avoid it being edited in the NeedStringArray constructors.
integer is private, so it cannot be accessed by NeedInteger. you'll have to make it public or use a setter or getter and you'll need to use Main.integer since it's static.
Generally, you set in the Constructor.
Pass in the variable to the class constructor.
An array reference would be just that--a reference.
Or you could pass in the class itself, or use a static (meh).
Per your comment I'd say you can either host your array in a singleton
or as others suggested have the second class accept the reference to the array in the constructor. You can then use Dependency Injection framework (e.g. Guice) to get wire them up
I need a class which creates Objects assigning an ID to each Object created. This ID is as usual an int attribute to the class. I want this value (ID) to be increased each time an Object is created and then to be assigned to that Object starting with 1. It strikes me that I need a static int attribute.
How can I initialize this static attribute?
Should I create a separate method to do the increment of the ID (as an ID generator) which is invoked inside the constructor?
What is in general the most effective and well-designed manner to implement that?
You could also try java.util.concurrent.AtomicInteger, which generates IDs in
a atomic way and
sequential
You may use this in a static context like:
private static final AtomicInteger sequence = new AtomicInteger();
private SequenceGenerator() {}
public static int next() {
return sequence.incrementAndGet();
}
Just like you mention use a static int for the id, and increment it when creating new objects.
class MyObject {
private static int counter = 0;
public final int objectId;
MyObject() {
this.objectId = counter++;
}
}
Please note that you need to protect counter++ if MyObject is created by multiple threads (for example using AtomicInteger as the other answers suggest).
I would suggest to use AtomicInteger, which is thread-safe
class MyObject
{
private static AtomicInteger uniqueId=new AtomicInteger();
private int id;
MyObject()
{
id=uniqueId.getAndIncrement();
}
}