tags:

views:

1432

answers:

5

I have two classes, and want to include a static instance of one class inside the other and access the static fields from the second class via the first.

This is so I can have non-identical instances with the same name.

Class A 
{
    public static package1.Foo foo;
}

Class B 
{
    public static package2.Foo foo;
}


//package1
Foo 
{
    public final static int bar = 1;
}

// package2
Foo
{
    public final static int bar = 2;
}

// usage
assertEquals(A.foo.bar, 1);
assertEquals(B.foo.bar, 2);

This works, but I get a warning "The static field Foo.bar shoudl be accessed in a static way". Can someone explain why this is and offer a "correct" implementation.

I realize I could access the static instances directly, but if you have a long package hierarchy, that gets ugly:

assertEquals(net.FooCorp.divisions.A.package.Foo.bar, 1);
assertEquals(net.FooCorp.divisions.B.package.Foo.bar, 2);
+4  A: 

You should use:

Foo.bar

And not:

A.foo.bar

That's what the warning means.

The reason is that bar isn't a member of an instance of Foo. Rather, bar is global, on the class Foo. The compiler wants you to reference it globally rather than pretending it's a member of the instance.

Jason Cohen
His use case would require `import package1.Foo; import package2.Foo;`, which is illegal because it makes Foo ambiguous.
erickson
+1  A: 

There is no sense in putting these two static variables in these to classes as long as you only need to access static members. The compiler expects you to access them trough class name prefixes like:

package1.Foo.bar
package2.Foo.bar
axk
This "ugly" way is the correct way to eliminate the warning.
erickson
+1  A: 

Once you created the object in:

public static package1.Foo foo;

it isn't being accessed in a Static way. You will have to use the class name and, of course, the full package name to address the class since they have the same name on different packages

Fernando Barrocal
A: 

It's true that a Foo instance has access to Foo's static fields, but think about the word "static". It means "statically bound", at least in this case. Since A.foo is of type Foo, "A.foo.bar" is not going to ask the object for "bar", it's going to go straight to the class. That means that even if a subclass has a static field called "bar", and foo is an instance of that subclass, it's going to get Foo.bar, not FooSubclass.bar. Therefore it's a better idea to reference it by the class name, since if you try to take advantage of inheritance you'll shoot yourself in the foot.

Kevin Conner
+1  A: 

I agree with others that you're probably thinking about this the wrong way. With that out of the way, this may work for you if you are only accessing static members:

public class A {
    public static class Foo extends package1.Foo {}
}
public class B {
    public static class Foo extends package2.Foo {}
}
jon
Thanks, that's the way to do it, even if it isn't the "java way". I knew it was possible because I could create the static inner class, and it wouldn't give errors, but that would be a maintenance nightmare, and hence rightly discouraged.
fijiaaron