I have two separate programs in java, and I have saved them in two different files. I want to use a variable (which is in the first program) in the second program.
How to do this?
Depends what you mean by "want to use a variable in another program". How are you defining your variables? The two "programs" must be two separate classes, so you'll be defining a variable as a class member, most likely. So, in you first class, you could have something like
public class ClassA {
public int variable;
...
}
and then in your second class you coul access it like so:
public class ClassB {
public ClassB() {
int var = new ClassA().variable;
}
}
Depending on how you define that variable (public/private/protected and static/instance), the way to access it would be different.
I am going to assume a few things here. The first assumption is that you are trying to access a variable in a different class and the second assumption is that those classes are in the same package most likely the default package. So to access a variable in class A from class B you need to instantiate class A.
ClassA.java
public class ClassA{
public int mMyInt = 10;
}
ClassB.java
public class ClassB{
public ClassB(){
ClassA myClass = new ClassA();
System.out.println(myClass.mMyInt);
}
public static void main(String args[]){
ClassB app = new ClassB();
}
}
I hope this helps.
Related
I have this scenario:
public class A
{
private final Integer index;
public Integer getIndex() { return index; }
public static class B
{
//unimportant
}
}
public class C extends B
{
//how to reference getIndex() here?
}
How can I call getIndex() in class C's body?
Odd scenario... but you'd have to move class C to also be an inner class inside class A. Shrug? Curious why are you extending an inner class in the first place? What are the restrictions of the design that are causing this? Not judging you at all. Having the thinking behind the design could aide in possibly finding an alternative solution.
public class A
{
// make sure final value is set here or in constructor
private final Integer index = 0;
public Integer getIndex() { return index; }
public static class B
{
//unimportant
}
//Doesn't make much sense... but...
public class C extends B
{
//can now call getIndex()
public void callGetIndex() {
getIndex();
}
}
}
Bonus research:
For those that are maybe as curious as me and thought about using this to reference the function from another file. If you compile C in another file, and try accessing getIndex by using the enclosing this:
A.this.getIndex();
Sadly that won't work because even though C extends B, it still needs to be enclosed by A for that methodology to work. You get this compile time error:
C.java:5: error: not an enclosing class: A
A.this.getIndex();
^
1 error
Hey cool! another answer, based off #mzl's answer below:
So interestingly enough, You can keep B static and extend both classes to get what you want to do. This is useful for example if you can not edit file A.java, because A.java is 3rd party functionality. (give #mzl credit here for his answer below)
Here is how you'd do it that way! ( Tested this compiles via javac A.java C.java )
A.java
public class A
{
private final Integer index = 0;
public Integer getIndex() { return index; }
public static class B
{
//unimportant
}
}
C.java
public class C extends A
{
public class D extends A.B {
//can now call getIndex()
public void callGetIndex() {
getIndex();
}
}
}
I've created a static over flow project proving #mzl's theory here:
https://github.com/davethomas11/stackoverflow_Q_39441077
One gothcha. You'll notice I create an instance of C before D to make sure there is access to getIndex(). I haven't tested what happens if you instantiate D directly I will do that later and post the results.
Late update on that instantiate D directly test.
I added C.D testD = new C.D(); in my static main function:
$ sh build.sh
StackOverflowQuestion39441077.java:5: error: an enclosing instance that contains C.D is required
C.D testD = new C.D();
^
1 error
The compiler helps us by not letting us do this.
If you want to extend (non-statically) a inner class you must extend the outer class aswell.
You could do it this way:
public class A
{
private final Integer index;
public Integer getIndex() { return index; }
public static class B {}
}
public class D extends A{
public class C extends B{}
}
You can't. C extends B which does not have a getIndex() method. C must extend A to inherit that method.
(I feel it is an interesting theoretical question but with little meaning in practice.)
You can't event access A.getIndex from B because B is static, and getIndex is not, so to invoke getIndex you need a non-null instance of A.
Assuming you could make B non-static, you couldn't either, because your scheme becomes contradictory:
In one hand, class B is inner, so to instantiate a new object a previous non-null instance of A is required:
A a=new A();
B b=a.new B();
But in the other hand, class C is a top-level (not inner) class, so it may be directly instantiated. However, being a subclass of B, it is subject to the same restrictions as its superclass: It needs an instance of A. Contradictory!
The only way I think to make it work is to declare getIndex static, so no instance of A would be needed (in fact, neither subclassing from B would be a problem).
I understand that protected access means that one can access the member within the package and any subclass, regardless of the package. What I find hard to understand is that, in a subclass, when I create an object of the class which has the protected member, I get a "not visible" error?
This is demonstrated by the following code (which is an expanded version based on an answer by YiFan Wu). Note that I have the same lines of code inside and outside of the package. Thus I have two questions:
Why does using the object change everything?
This object access difference does not happen within the package i.e. see test() in class A1.
package a;
public class A{
protected int a;
}
class A1{
public void test(){
A ref = new A();
ref.a=8; // no issue
}
}
package b;
public class B extends A{
}
package c;
public class C extends B{
public void accessField(){
a = 2; //That works.
A ref = new A();
ref.a=8; // not visible!!
}
}
Any help much appreciated...
Thanks,
Sean.
Because C is in another package, and you're creating an A, not a subclass of A.
Flip the question on its head: why should it be visible? You already know the packaging rules, and you already know the field access rules.
In the last case you're making a new instance of an A object. This is completely different from using an instance of the subclass to access its parent class's members.
When you create a subclass, it creates a parent class first. The only subclass that has access to protected members in the parent instance is that subclass that the parent class was created with.
Simple question. I made a class called Tester1 which extends another called Tester2. Tester2 contains a public string called 'ABC'.
Here is Tester1:
public class Tester1 extends Tester2
{
public Tester1()
{
ABC = "Hello";
}
}
If I instead change line 5 to
super.ABC = "Hello";
am I still doing the exact same thing?
Yes. There's only one ABC variable within your object. But please don't make fields public in the first place. Fields should pretty much always be private.
If you declared a variable ABC within Tester1 as well, then there'd be a difference - the field in Tester1 would hide the field in Tester2, but using super you'd still be referring to the field within Tester2. But don't do that, either - hiding variables is a really quick way to make code unmaintainable.
Sample code:
// Please don't write code like this. It's horrible.
class Super {
public int x;
}
class Sub extends Super {
public int x;
public Sub() {
x = 10;
super.x = 5;
}
}
public class Test {
public static void main(String[] args) {
Sub sub = new Sub();
Super sup = sub;
System.out.println(sub.x); // Prints 10
System.out.println(sup.x); // Prints 5
}
}
Yes, the super qualifier is unnecessary but works the same. To clarify:
public static class Fruit {
protected String color;
protected static int count;
}
public static class Apple extends Fruit {
public Apple() {
color = "red";
super.color = "red"; // Works the same
count++;
super.count++; // Works the same
}
}
Well first thing is that the variable ABC must be declared in the class Tester2. If it is then yes you are.
You are. Given that ABC is visible to Tester1 (the child class), it is assumed to be declared anything but private and that is why it is visible to a sub-class. In this case, using super.ABC is simply reinforcing the fact that the variable is defined in the parent.
If, on the other hand, ABC had been marked private in the parent class, there would be no way of accessing that variable from a child class - even if super is used (without using some fancy reflection, of course).
Another thing to note, is that if the variable had been defined private in the parent class, you could define a variable with the exact same name in the child class. But again, super would not grant you access to the parent variable.
Before you start reading I would like to clarify:
I have already thought of other designs and work arounds
I'm only interested in the problem I exposed and not "changing" it (so no solutions such as delete the points in A and create new points fields in B and C...
lets consider the following code:
public class A {
protected cpVect[][] points = null;
...
}
and its classes that inherits it:
public class B extends A{
...
}
public class C extends A{
...
}
so far so good.
my problem is that for B and C contains arrays of points that will be created in the constructor using something like
if(points == null){calculate points code}
the problem is as follow
points in A can't be static because the dimensions are different in B and C.
but every instance of B will share the B points and every instance of C will share the C points. (in other words a Square will always be a square and a triangle will always be a triangle). and therefore I want to have the B:points and C:points static so that i don't get duplicates of the values for every instance.
So is there a way to redefine points as static in B and C when it is not static in A?
If you access points solely through property methods (getters/setters) you can do whatever you want in the subclasses. If you use inheritance, A will have to be an abstract class. Otherwise you'd always carry around the empty points variable in A (losing 8 bytes, probably).
In this case the hierarchy would look like this:
abstract class A {
abstract public cpVect[][] getPoints();
// more methods ...
}
public class B extends A {
private final static cpVect[][] POINTS = calculatePoints();
#Override
public cpVect[][] getPoints() {
return POINTS;
}
private cpVect[][] calculatePoints() {
// ...
}
}
And the same for C. If A includes no other state or functionality, you should make it an interface.
You can't make the field static, but you could make it a singleton. You'll have multiple references to the singleton, but you'll only need one copy of each points array. For example, in B:
class B extends A {
private cpVect[][] B_points = null;
public B() {
if (B_points == null)
B_points = create_B_points();
points = B_points;
}
}
If multithreaded, you'll need to add synchronization.
(Sorry for earlier half-finished version. The SO editor seems quirky in Chrome).
There is no significance of static and non-static in inheritance. ie if you have a member variable in a parent class then you can have the same name for the static member of the child class. as shown
class test {
public int a;
}
class test1 extends test {
public static int a;
}
And through objects you can access a of test.
through class test1 you can access static a of test1. as both are independent.
You cannot have a same variable as the member in parent and static in child.
iI have some trouble getting sth like this to work in java:
public class ClassA {
public static ClassB PointerToB;
public static ClassC PointerToC;
public ClassA() {
PointerToB = new ClassB();
PointerToC = new ClassC();
PointerToB.doSthB();
}
}
public class ClassB {
public void doSthB() {
ClassA.PointerToC.doSthC();
}
}
public class ClassC {
public void doSthC() {
// ...
}
}
say i have these classes where my "main" class ("A") has several members. these pointers to other objects ("B", "C") are made static so code in "B" can access (non-static) methods in "C".
i know that static methods can only access other static methods and/or variables, but since the REFERENCE to these classes is static - and not the actual class itself - it should work fine this way - shouldn't it?
i'm a bit stuck here, since this kind of access crashes my application all the time :(
i need ClassB to access (non-static) methods in ClassC without passing all the references to A or C along. how do i do this?
Well, other than your constructor for ClassA being malformed (you're missing the brackets), that code compiles... but until you construct an instance of ClassA, both PointerToB and PointerToC will be null. If you want to just initialize them once, do so in static initializers - e.g. with the declarations:
public static ClassB PointerToB = new ClassB();
public static ClassC PointerToC = new ClassC();
Even so, there are two nasty bits of design here (IMO):
Public mutable fields are almost always a mistake
If everything uses ClassA.PointerToB and ClassA.PointerToC, you've effectively got singletons, with the accompanying downsides. Consider dependency injection instead.
When you say "you're stuck", do you mean you're getting NullPointerExceptions?
The variables PointerToB and PointerToC are static and will indeed be set by ClassA's constructor. However, this will only be run when an instance of ClassA is created.
What you were probably thinking of instead is a static initialiser block, which will be run when the class is loaded:
public class ClassA {
public static ClassB PointerToB;
public static ClassC PointerToC;
static {
PointerToB = new ClassB();
PointerToC = new ClassC();
}
public ClassA() {
PointerToB.doSthB();
}
}
Now whenever you access these variables they will be non-null. In this particular case, since you're not doing anything complicated, you may as well initialise them in the declaration:
public class ClassA {
public static ClassB PointerToB = new ClassB();
public static ClassC PointerToC = new ClassC();
}
This is functionally identical, but is arguably easier to write and understand.
Edit: As an aside, note that your code is actually quite nasty as it is now - there's a hidden temporal dependence, in that it would appear to work correctly so long as some bit of code constructed an instance of ClassA before you accessed the static variables. This could have worked quite happily (by coincidence) for months, before someone makes some tiny change (e.g. create a ClassA on demand rather than eagerly) and BANG, all of a sudden some completely unrelated code starts breaking.
Even worse than this temporal dependency, you're opening yourself up to race conditions that you probably hadn't even considered. Both of my versions above will guarantee that the static variables are initialised before you can do anything in the class, but this isn't the case with your version. You're setting them on each and every time that the class is constructed. If one thread's calling the constructor while another thread is accessing the variable, the results are undefined and could manifest as "random" crashes, weird data issues or other things.
Even if you avoid this, the actual object references will change over time, so you might call something like PointerToC.doSthC() (let's say it increments a counter in C) - this will correctly make the counter 1, but at a later point in the program, PointerToC has been reset to a new instance of ClassC and the counter is back at zero again!
I don't mean to show you up or anything by this, merely to point out how it's important to think about data consistency issues - and how just because something compiles, and in fact even if it works (right now) it's not necessarily correct.
i need ClassB to access (non-static) methods in ClassC without passing all the references to A or C along. how do i do this?
Then ClassB needs a reference to an instance of C - no real way around this.
Instead of ClassB accessing C via a static reference in A, why not write B a little differently?
public class ClassB {
public void doSthB(ClassC c) {
c.doSthC();
}
}
This cannot ever work. static means that different instances of a class can never have different values for a field, and yet that is exactly what you say you want to happen. Instead of making PointerToB static, provide the objects you use directly with references to the collaborators they need.
(You also seem confused about the difference between classes and objects. Try to give a non-generic example to receive more useful help here!)
I think the solution you're looking for is the singleton pattern:
public class ClassA{
private static final class InstanceHolder{
private static final ClassA INSTANCE = new ClassA();
private InstanceHolder(){
}
}
public static ClassA getInstance(){
return InstanceHolder.INSTANCE;
}
}
public class ClassB{
private static final class InstanceHolder{
private static final ClassB INSTANCE = new ClassB();
private InstanceHolder(){
}
}
public static ClassB getInstance(){
return InstanceHolder.INSTANCE;
}
}
that way, the classes are decoupled from each other (a bit), and you can access them independently:
// inside ClassA
public void doSthB() {
ClassB.getInstance().doSthC();
}
However, Singletons are evil, so be careful what you are doing. (But what you are doing now is arguably even more evil)