Having something like in Java:
class A {}
class B {private A a;}
class C {private A a;}
How could I know which is the class that declared a ?
I.e. I want to get class B or class C
Any ideas are appreciated.
Regards
You couldn't just with the structure you've specified. You'd have to pass a reference to an instance of B or C into A's constructor, then write some logic to determine the type passed in.
class A {
public void print(){
String className = new Exception().getStackTrace()[1].getClassName();
System.out.println(className);
}
}
class A1 {
private A a;
public A1(){
a= new A();
a.print();
}
}
class A2 {
private A a;
public A2(){
a= new A();
a.print();
}
}
public class C {
public static void main(String[] args) {
A1 a1= new A1();
A2 a2 = new A2();
}
}
You have to do someting like:
class A {
boolean itWasC;
public A( C objectC ) {
itWasC = true;
}
public A( B objectB ) {
itWasC = false;
}
}
And once you create an object of class "A" from class B or class C pass this to the constructor. For example: A objectA = new A( this )
It is weird, and you can't do it without instanciating objects.
As i understand the question you need to find all usages of class A (type usages) in your code (Please correct me if i'm wrong).
It depend on your IDE and the installed plugins for code inspection, most IDE's provide such a functionality, in Eclipse for example you can right click a Class and select "References->Project"
And if your IDE does not have this there are alot of tools for java, take a look at: A tool like ReSharper, but for Java?
you cannot do that in java unless you have a reference of the Object in Class A... definitely not through programatically nor in runtime.
But if you just want to find out the classes that are referencing Class A , one option is to rename the class to something else and try to compile.
And Voila , compiler would list all the classes that Reference Class A , but cannot resolve to a type.
Another alternative ,would be to use Reflections to find out the Variables in a Class and compare if the type of the variable is of Class A type
Heres a sample Program i wrote to do just that
import java.lang.reflect.Field;
import com.test.ClassA;
package com.test;
public class ClassA {
}
public class ClassB {
private ClassA classA;
public static void main(String[] args) throws Exception,
NoSuchFieldException {
Field classVariable = ClassB.class
.getDeclaredField("classA");
classVariable.setAccessible(true);
System.out.println(classVariable.getType());
System.out.println(ClassA.class);
if (ClassA.class.equals(classVariable.getType())) {
System.out.println("Class A is referenced");
}
}
}
Result
class com.test.ClassA
class com.test.ClassA
Class A is referenced
Related
I'm doing this for educational purposes, so imagine that i have an objects called A, B and C, if B calls a method on A, A will do it, if C calls a method on A, A won't do it.
An analouges, Imaging A is you, B is your dad and C is someone else, if your dad tells you something, you have to do it without asking, if someone else tells you something, you aren't obliged to do it.
I didn't find an answer for this behavior, please someone can describe how to do it, and shows me an example in Java.
This code would be one way to do it if you included a list of bosses in the constructor:
public class Me {
private ArrayList<Object> bosses=new ArrayList<Object>();
public Me(ArrayList<Object> myBosses) {
this.bosses=myBosses;
}
public void AnOrderToDo(Object orderer,int randomArg){
for(Object o:bosses){
if(o==orderer){
//TODO method code here
}
}
}
}
You can create a package containing only classes A and B and use the default access modifier for the methods that should not be called from other classes.
The default access modifier allows only the class itself and classes in the other packages to see the methods, so if C is in another package will not even be able to see the method.
Example:
Class A in package stackoverflow.defaultModifier
package stackoverflow.defaultModifier;
public class A {
//NOTICE THE ABSENCE OF PUBLIC/PRIVATE/PROTECTED, is using the default access modifier
void printHello(){
System.out.println("hello");
}
}
Class B in package stackoverflow.defaultModifier can access to printHello()
package stackoverflow.defaultModifier;
public class B {
public static void main(String[] args) {
A a = new A();
a.printHello();
}
}
Class C in package stackoverflow.externalClasses cannot access printHello() (Error: printHello() is not public in class A, cannot be accessed from outside package)
package stackoverflow.externalClasses;
import stackoverflow.defaultModifier.A;
public class C {
public static void main(String[] args) {
A a = new A();
a.printHell(); //compilation error!
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
For example:
public class example {
public class A {
public void speak() {
System.out.println("Hello!");
}
}
public class B extends A {
public void response() {
System.out.println("How are you?");
}
}
public class C extends A {
public void responseTwo() {
System.out.println("Good!");
}
}
A test1 = new A(); // it's legal.
A test2 = new B(); // it's also legal.
B test3 = new C(); // not legal. Why is that?
Unless there's some information you haven't shared that should be fine since B and C have distinct names. They may have the same fields or not; it doesn't matter.
The declaration of that classes are RIGHT. You cannot declare more than one public class in a file, but you can declare public classes inside other class. But you can only use them in your class in which they are declared.
This is illegal because B and C are diferents classes. See:
A test1 = new A(); // it's legal.
A test2 = new B(); // it's also legal.
B test3 = new C(); // not legal. Why is that?**
You are assigning an object of type C to a variable of type B. They are "brothers" not parent/child classes.
You can do:
A test = new C();
Your classes hierachy are like this:
A
----|----
| |
B C
I think you mean in the same source file. The answer is NO.
(Compiler will warn you with the following message : The public type B must be defined in its own file or The public type C must be defined in its own file)
You can define inner classes though, as below :
public class A {
//blah blah blah
public class B extends A {
//blah blah blah
}
public class C extends A {
//blah blah blah
}
}
All of these classes should have their own "file"
Is you are using Eclipse it's basically making a new class.
Unless there is any information that you haven't shared with us.
You can't just put multiple classes in the same "file" (class file)
You need to create separate class files for each class you wish to have in your program.
What do you mean by "same program"?
You can create multiple classes within same FILE with .java extension, but only one class will be allowed to be public, for example:
public class A {
}
class B extends A{
}
class C extends B{
}
and filename should be the one with public modifier in this case it will be A.java
I have a function in Class A which I would like to change the value of a field in Class B.
Class C has my main() and creates a new instance of class B and Class A. Class A is from an API and one of their functions is a listener function. I would like for that listener function to be able to change the field of Class B, but when I write the code for the listener function, it doesn't recognize Class B's instance.
How do I reference that instance?
Example code:
public class A {
public void listenermethod(){
//can't reference Binstance <-------
}
}
public class B {
B.field = 1;
}
public class C {
A Ainstance = new A();
B Binstance = new B();
}
You should give A class a private B field, and then you can call the public methods from B on this field as needed. If you need to create both A and B instances in a separate class (C) you should give your A class a public void setB(B b) setter method.
A.java
class A {
private B b;
public void setB(B b) {
this.b = b;
}
public void listenerMethod() {
if (b != null) {
b.someBMethod();
}
}
}
C.java
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.setB(b);
a.listenerMethod();
}
}
You have to be able to modify both class C and class A. Rewrite the class A method to
public void listenermethod(Binstance theB){
theB.something = "some_value";
}
Now when you call class A, pass in the Binstance. If you can't modify class A, then your task can't be done.
An instance by definition belongs to an object. Therefore, your class A must either have an object of class B as a member:
Class A{
private B instance_of_b;
}
now you can access B members like this:
instance_of_b.member
or the field belonging to class B could be static and then A could access it through the class.
B.member
Also make sure you know the meaning of accessor keywords (private,protected,[friendly],public).
Good day,
I have the following problem:
class B extends class A and methods of both are called by another method in another class after instantiating class B (example follows):
public class A{
//fields
//constructors
//methods
}
public class B extends A{
//fields
//constructors
//methods
}
public class CALLER{
public A getA(enum E){
return Factory.getB(otherobject,E);
}
}
public class Factory{
public static B getB(object o,enum e){
//do something with enums and get B
b = new B();
//populate b
return b;
}
}
Class B does not override any method of class A.
Somehow at compile time this doesn't get any error but at runtime class CALLER excepts: java.lang.NoSuchMethodError: Factory.getB(object,enum) A
My question is: if B extends A why a method from a different class can't return A even if its return clause returns a B object directly?
In fact changing:
public static B getB(object, enum);
with
public static A getB(object, enum);
solves the exception but then I get another exception (classCast) because obviously in other parts of the code it is awaiting a B type object, not an A.
Thanks in advance.
You would get this exception if you had compiled CALLER.java with another version of Factory.java that would have getB returning A, then updated Factory.java so that getB returns B, then recompiled Factory.java but not CALLER.java
UPDATE:
Perhaps you want to do something like this:
public abstract class Factory {
public abstract A getInstance(object o, enum e);
}
public class FactoryB extends Factory {
#Override
public B getInstance(object o,enum e){
//do something with enums and get B
b = new B();
//populate b
return b;
}
}
But the factory would then need to be instanciated.
The first one looks like a reflection error. The java reflection classes look for the exact method signature "A getB(Object,Enum)" and not "B getB(Object,Enum)".
The second, as long as you actually create an object of type B in your getB(..) method, it will return this object. The classCast exception will only be thrown if you create a new A instead of a new B.
In Python, class methods can be inherited. e.g.
>>> class A:
... #classmethod
... def main(cls):
... return cls()
...
>>> class B(A): pass
...
>>> b=B.main()
>>> b
<__main__.B instance at 0x00A6FA58>
How would you do the equivalent in Java? I currently have:
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
public static void main( String[] arg ) {
new A().run();
}
}
public class B extends A{
#Override
public void show(){
System.out.println("B");
}
}
I'd like to call B.main() and have it print "B", but clearly it will print "A" instead, since "new A()" is hardcoded.
How would you change "new A()" so that it's parameterized to use the class it's in when called, and not the hard-coded class A?
Static methods in java are not classmethods they are staticmethods. In general it is not possible to know which class reference the static method was called from.
Your class B does not have a main method and static methods are not inherited.
The only way I can see this happening is to find whatever is calling A.main( String[] arg ) and change it to call B.main instead.
B.main:
public static void main( String[] arg ) {
new B().run();
}
How is your program started? Is there a batch file, shortcut, etc? Something you can change? Where does A.main get called?
I think this isn't possible. Here's why:
In Java, the implementation of a method is determined by the instance's run-time type. So, to execute B.show(), you need to have an instance of B. The only way I could see to do this, if the method that constructs the instance is supposed to be inherited, is to use Class.newInstance() to construct an instance of a type that's not known at runtime.
The problem with that is that within a static method, you have no reference to the containing class, so you don't know whose newInstance method to call.
Why do you want to do this, though? There may be some better way to achieve whatever it is you want to achieve.
In your example I wouldn't put your main method inside of A. This is setup as the entry point into the system (you can't be in B if you are specifically entering into A).
In the example below I created class A, B, and C. Class C instantiates A and B and runs them. Notice that in C I created an A, a B, and another A that I instantiate as a B. My output is:
A
B
B
Hopefully this makes sense.
public class A {
public void show(){
System.out.println("A");
}
public void run(){
show();
}
}
public class B extends A {
#Override
public void show(){
System.out.println("B");
}
}
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
A anothera = new B();
a.show();
b.show();
anothera.show();
}
}