getting the current class object - java

I have three classes.. A,B,C.
In both classes B and C i have a static string variable "name" which contains the name of B and C, as-
class B
{
static name;
public static void main(String args[])
{
name="Class B";
A.getName();
}
I am calling class A's getName method from class B and C.. Class A is as follows:
class A
{
getName()
{
System.out.println(this class called me);
}
}
class C is:
class C
{
static name;
public static void main(String args[])
{
name="Class C";
A.getName();
}
Now my question is, what code should i use in place of "this class called me" in class A so that i get the name of whichever class calls A! I hope i am clear!!

Your A.getName method cannot know what class's code called it. You have to pass that information into it.
Okay, so that's not strictly true, you could figure it out by generating a stack trace and inspecting that. But it would be a very bad idea. In general, if a method needs to know something, you either A) Make it part of an instance that has that information as instance data, or B) Pass the information into it as an argument.

class A {
getName()
{
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
int lastStackElement = stackTraceElements.length-1;
String callingObjectsName = stackTraceElements[lastStackElement].getClassName();
System.out.println(callingObjectsName + " called me.");
}
}

Modify your code to something like this:
class A
{
getName(String className)
{
System.out.println(className);
}
}
and use it like :
class B
{
static name;
public static void main(String args[])
{
name="Class B";
A.getName(name);
}
}

It sounds like what you're really trying to do is to pass information from one stack frame to another one -- and specifically, from a frame A to a frame B, where A invoked B. This is an easy thing to do, and I think you're over-engineering it.
public class B {
static String name = ...
public static void main(String[] args) {
A.getName(name);
}
}
public class C {
static String name = ...
public static void main(String[] args) {
A.getName(name);
}
}
public class A {
public static void getName(String name) {
System.out.println(name);
}
}
Your approach would require:
Getting the stack trace
Using that to get the calling stack frame, which is element 1 in the stack trace array
Using that to get the class name for the calling method
Using Class.forName to get the Class<?> object
Calling getField("name") on that Class<?> object to get a Field object
(optional but recommended) Confirming that the Field represents static field of type String
calling get(null) on the Field to get its value (the null represents the object for which you want the field -- since the field is static and thus not tied to any object, this argument is ignored), and casting this value down to String
Or, instead you could:
Just pass the name to the function that needs it.
Your approach also requires that the name field be static, since there's no way to get the calling instance (even though you can get the calling instance's class). The simpler approach works even if name is an instance field.

Related

Is it possible to avoid using "static" when call variable from another class?

Is it able to avoid using "static" when call variable from another class? thank you very much
Here is my code.
class Hello {
public static String say = "Hello World"; //I using static
public void born() {
System.out.println(say);
}
}
public class SayHello extends Hello {
public static void main(String[] args) {
Hello myHello = new Hello();
myHello.born();
System.out.println(say);
}
The Output:
Hello World
Hello World
If I use public String say = "Hello World";
it output Hello World null
AnyIdea to avoid using "static" when call variable from another class?
thank you very much
If you remove the static, it will not compile. Static fields can be marked private, if you want to hide them. So then they are reachable by all instances of the class Hello only. The proper way of modifying or getting would be:
class Main extends Hello {
public static void main(String[] args) throws Exception {
Hello myHello = new Hello();
myHello.born();
// System.out.println(say); //doesn't allow access
// System.out.println(Hello.say); //doesn't allow access
System.out.println(myHello.getSay());
}
}
class Hello {
private static String say = "Hello World"; //private
public void born() {
System.out.println(say);
}
public String getSay() {
return say;
}
}
A static variable is common to all the instances (or objects) of the class because it is a class level variable. In other words you can say that only a single copy of static variable is created and shared among all the instances of the class.
So if you don't want to use static, then you can't use it in the other instances of class.
Yes, if you don't declare it static you can reference it from an instance: myHello.say.
It is the same as for calling a function.
public class SayHello extends Hello {
public static void main(String[] args) {
Hello myHello = new Hello();
myHello.born();
System.out.println(myHello.say);
}
}
For a constant, ie. a String that never changes and is the same for all instances of the class, it makes sense to declare it static and use it as such.
If you don't mark the string as static you will get a compilation error because when you do System.out.println(say) in the main method you are using say in a static context (since the main method must be static).
If you remove System.out.println(say); and just leave myHello.born(); then there's no need for say to be static because you'll only be using it from non-static methods (i.e. the born() method). You can see it in this example where I commented that line and defined say as not being static.
Another option would be to make the println like this, since the variable is public: System.out.println(myHello.say);

Simple pass of variable to new class, then output in Java

I've seen this question asked in several ways, but the code is usually specific to the user, and I get lost a little. If I'm missing a nice clear and simple explanation, I'm sorry! I just need to understand this concept, and I've gotten lost on the repeats that I've seen. So I've simplified my own problem as much as I possibly can, to get at the root of the issue.
The goal is to have a main class that I ask for variables, and then have those user-inputted variables assessed by a method in a separate class, with a message returned depending on what the variables are.
import java.io.*;
public class MainClass {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
String A;
String B;
try {
System.out.println("Is A present?");
A = reader.readLine();
System.out.println("Is B present?");
B = reader.readLine();
Assess test = new Assess();
} catch (IOException e){
System.out.println("Error reading from user");
}
}
}
And the method I'm trying to use is:
public class Assess extends MainClass {
public static void main(String[] args) {
String A = MainClass.A;
String B = MainClass.B;
if ((A.compareToIgnoreCase("yes")==0) &&
((B.compareToIgnoreCase("yes")==0) | (B.compareToIgnoreCase("maybe")==0)))
{
System.out.println("Success!");
}
else {
System.out.println ("Failure");
}
}
}
I recognize that I'm not properly asking for the output, but I can't even get there and figure out what the heck I'm doing there until I get the thing to compile at all, and I can't do THAT until I figure out how to properly pass values between classes. I know there's fancy ways of doing it, such as with arrays. I'm looking for the conceptually simplest way of sending a variable inputted from inside one class to another class; I need to understand the basic concept here, and I know this is super elementary but I'm just being dumb, and reading what might be duplicate questions hasn't helped.
I know how to do it if the variable is static and declared globally at the beginning, but not how to send it from within the subclass (I know it's impossible to send directly from the subclass...right? I have to set it somehow, and then pull that set value into the other class).
In order to pass variables to an object you have either two options
Constructor - will pass parameter when creating the object
Mutator method - will pass parameters when you call the method
For example in your Main class:
Assess assess = new Assess(A, B);
Or:
Assess assess = new Assess();
assess.setA(A);
assess.setB(B);
In your Assess class you have to add a constructor method
public Assess(String A, String B)
Or setter methods
public void setA(String A)
public void setB(String B)
Also, Assess class should not extend the main class and contain a static main method, it has nothing to do with the main class.
Below there is a code example!
Assess.java
public class Assess {
private a;
private b;
public Assess(String a, String b) {
this.a = a;
this.b = b;
}
public boolean check() {
if ((A.compareToIgnoreCase("yes")==0) &&
((B.compareToIgnoreCase("yes")==0) ||
(B.compareToIgnoreCase("maybe")==0)))
{
System.out.println("Success!");
return true;
} else {
System.out.println ("Failure");
return false;
}
MainClass .java
public class MainClass {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
String A;
String B;
try {
System.out.println("Is A present?");
A = reader.readLine();
System.out.println("Is B present?");
B = reader.readLine();
Assess test = new Assess(A, B);
boolean isBothPresent = test.check();
// ................
} catch (IOException e){
System.out.println("Error reading from user");
}
}
I think what you're looking for are method parameters.
In a method definition, you define the method name and the parameters it takes. If you have a method assess that takes a string and returns an integer, for example, you would write:
public int assess(String valueToAssess)
and follow it with code to do whatever you wanted with valueToAssess to determine what integer you wanted to return. When you had decided that i was the int to return, you would put the statement
return i;
into the method; that terminates the method and returns that value to the caller.
The caller obtains the string to be assesed, then calls the method and passes in that string. So it's more of a push than a pull, if you see what I mean.
...
String a = reader.readLine();
int answer = assess(a);
System.out.println("I've decided the answer is " + answer);
Is that what you're looking for?
A subclass will have access to the public members of the superclass. If you want to access a member using {class}.{member} (i.e. MainClass.A) it needs to be statically declared outside of a method.
public class MainClass {
public static String A;
public static String B;
...
}
public class Subclass {
public static void main(String[] args) {
// You can access MainClass.A and MainClass.B here
}
}
Likely a better option is to create a class that has these two Strings as objects that can be manipulated then passed in to the Assess class
public class MainClass {
public String A;
public String B;
public static void main(String[] args) {
// Manipulate A, B, assign values, etc.
Assess assessObject = new Assess(A, B);
if (assessObject.isValidInput()) {
System.out.println("Success!");
} else {
System.out.println("Success!");
}
}
}
public class Assess {
String response1;
String response2;
public Assess (String A, String B) {
response1 = A;
response2 = B;
}
public boolean isValidInput() {
// Put your success/fail logic here
return (response1.compareToIgnoreCase("yes") == 0);
}
}
First you don't need inheritance. Have one class your main class contain main take the main out of Assess class. Create a constructor or setter methods to set the variables in the Assess class.
For instance.
public class MainClass
{
public static void main(String[] Args)
{
Assess ns = new Assess( );
ns.setterMethod(variable to set);
}
}
I'm not 100% sure of your problem, but it sounds like you just need to access variables that exist in one class from a subclass. There are several ways...
You can make them public static variables and reference them as you show in your Assess class. However, they are in the wrong location in MainClass use
public static String A, B;
You can make those variables either public or protected in the parent class (MainClass in your example). Public is NOT recommended as you would not know who or what modified them. You would reference these from the sub-class as if present in the sub-class.
public String A, B; // Bad practice, who modified these?
protected String A, B;
The method that might elicit the least debate is to make them private members and use "accessors" (getters and setters). This makes them accessible programmatically which lets you set breakpoints to catch the culprit that is modifying them, and also let you implement many patterns, such as observer, etc., so that modification of these can invoke services as needed. If "A" were the path to a log file, changing its value could also cause the old log to close and the new one to be opened - just by changing the name of the file.
private String A, B;
public setA(String newValue) {
A = newValue;
}
public String getA() {
return A;
}
BUT ...
Your question says "send to the subclass", but confounded by your knowing how to do this using global variables. I would say that the simplest way is to provide the values with the constructor, effectively injecting the values.
There are other ways, however, your example shows the assessment performed by the constructor. If your Assess class had a separate method to perform the assessment, you would just call that with the variables as arguments.
Your example is confusing since both classes have main methods and the child class does the assessing - I would think you would want the opposite - Have MainClass extend Assess, making "MainClass an Assess'or", let main assign the Strings to Assess' values (or pass them as arguments) to the parent class' "assess" method ("super" added for clarity):
super.setA(local_a);
super.setB(local_b);
super.assess();
or
super.assess(A, B);

Can `greetSomeone("world")` be replaced by `greetSomeone(name)`? Is there any side effect to this change?

I'm new to Java and is trying to learn the concept of inner class. I saw the code below from Java tutorial Oracle. My question is, for
String name = "world";
#Override
public void greet() {
greetSomeone("world");
}
Can greetSomeone("world") be replaced by greetSomeone(name). The reason why I'm asking this question is because I have noticed if greetSomeone("world") is indeed replaced by greetSomeone(name), inside the public void greetSomeone() method, the passed "name" argument will be set to itself. I was just wondering if there are side effect to code like this?
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
#Override
public void greet() {
greetSomeone("world");
}
#Override
public void greetSomeone(String someone) {
name = someone;
System.out.println("hello " + name);
}
}
HelloWorld eg1 = new EnglishGreeting();
eg1.greet();
}
public static void main(String[] args) {
HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
First of all why is that #Override annotation there?
You will use Override when you want to change the behaviour of the parent's methods. Your parent's methods have no behaviour as it is an interface. As a further note I guess that it will teach you that the signature of an overriden method must always match the one from the parent.
Secondly the design is kind of dodgy. It can be simplified.
Thirdly yes you can refer to the String object name as it is defined in that class and you can access the object's primitive just by calling 'name'. Why will you not get the reference printed when System.out? Because the String object handles that for you ensuring the toString will show you the primitive. When you do System.out.print(myObject); The console will show you the Object default or the overriden toString method.
So if you create an object and you do System.out.print(myObject) you will see the reference. If you override toString returning "test" you will see test.
Technically, name can be passed and name = name; is valid Java.
However, this is a horrible design and was probably used for demonstrative purposes only. Don't do this.

Multiple classes basics, putting a print class into the main method

I am trying to see the basics for what is required to call in a second class, because tutorials and the book I am using are over-complicating it by using user input right now.
So here is what I tried. First is my main class and the second is the class I tried to call into the main method portraying just a simple text.
public class deck {
public static void main(String[] args) {
edward test = new edward();
System.out.print(test);
}
}
Other class:
public class edward {
public void message(int number) {
System.out.print("hello, this is text!");
}
}
How come this doesn't work?
If you could try to explain what I am doing or how this works a bit in detail that would be nice. I'm having a hard time with this part and getting a bit discouraged.
This does not work because you are printing a wrong thing: rather than printing test, you should call a method on it, like this:
public class deck {
public static void main(String[] args){
edward test = new edward();
test.message(123);
}
}
message(int) is a method (more specifically, an instance method). You call instance methods by specifying an instance on which the method is to be called (in your case, that is test), the name of the method, and its parameters.
The other kind of methods is static - i.e. like main. These methods do not require an instance, but they cannot access instance properties either.
Just an additional hint.
Every class in Java is derived from the java built in class "Object".
This common class offers some common methods.
In your case the method
public String toString()
is from interest.
You can override this method in your class edward and return the String you want.
public class edward {
#override
public String toString() {
return "hello, this is text!"
}
}
If you now use an object of class edward (test)t within the main method like you did it in your sample code
public static void main(String[] args) {
edward test = new edward();
System.out.println(test);
}
Then the text returnrd by the overriden toString() method would be printed out.
You use in this case the possibility to override methods from a super class (Object) and a subclass (edward).
Generally you would use the toString nethod to output the values of the fields (properties) of an object to show its current state.
If you not override the toString method you would get a String like eg this #ae23da which represents the current adress of the object test in memory.
public class deck
{
public static void main(String[] args)
{
edward test = new edward(); //1
System.out.print(test); //2
}
}
In line 1, you create a new edward object called test.
In line 2, you print the object itself. According to the Java API, print(Object)
Prints an object. The string produced by the String.valueOf(Object) method is translated into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.
I'm guessing that the output looked something like: edward#672563. That is because String.valueOf(obj) returns the type of obj (edward), followed by the character #, followed by the location in memory of obj (672563).
Here is some code that should do what you are attempting:
public class Deck //all class names should be capitalized
{
public static void main(String[] args)
{
Edward test = new Edward();
test.message(); //1
}
}
public class Edward
{
public void message() //`message` doesn't need a parameter
{
System.out.print("hello, this is text!");
}
}
In line 1, you call test's method message(). Calling a method executes the code that is in that method, so test.message() executes the line
System.out.print("hello, this is text!");
Here is a different way of doing the same thing:
public class Deck
{
public static void main(String[] args)
{
Edward test = new Edward();
System.out.println(test.message); //1
}
}
public class Edward
{
public String message = "hello, this is text!"; //2
}
In line 2, you create a new String "field" with the value of "hello, this is text!".
In line 1, you print the value of the field message contained in the object test.
If there are other parts of this code that you don't understand, feel free to comment on this answer!

Constructor code does not execute before object is created JAVA

I have recently played with code in java, and encountered this problem, that the code inside the constructor seems to be not executed, as the compiler throws the NullPointerException.
public class ObjectA {
protected static ObjectA oa;
private String message = "The message";
public ObjectA() {
oa = new ObjectA();
}
public static void main(String args[]) {
System.out.println(oa.message);
} }
Now when i move the creation of the object before the constructor, i.e. I do it in one line, then everything works fine.
Can anyone explain to me why does this happen, and where my understanding of the code is wrong?
Thanks in advance.
You're never calling the ObjectA() constructor, except in the ObjectA constructor. If you ever did call the constructor (e.g. from main), you'd get a stack overflow because you'd be recursing forever.
It's not really clear what you're trying to do or why you're using a static variable, but your code would be simpler as:
public class ObjectA {
private String message = "The message";
public static void main(String[] args) {
ObjectA oa = new ObjectA();
System.out.println(oa.message);
}
}
Also note that the compiler never throws an exception. It's very important to distinguish between compile-time errors (syntax errors etc) and execution-time errors (typically exceptions).
You need to move ObjectA oa = new ObjectA() to your main method.
Also, there is no need for this: protected static ObjectA oa;
You should copy/paste a Hello World program from a tutorial and see how it works.
You define a static variable oa but you only ever intialise it in the class's constructor. You never instantiate your class ObjectA so oa can only ever be null.
When you call your main method it tries to access the message variable of a null object, hence the NPE.
1) You never create an object
put:
ObjectA oa = new ObjectA();
in your main before your System.out.print.
2) set the message to public instead of private.
Hope something you need like this
public class ObjectA {
protected static ObjectA oa;
private String message = "The message";
public ObjectA() {
}
public static ObjectA getInstance() {
if (oa == null) {
oa = new ObjectA();
}
return oa;
}
public String getMessage() {
return message;
}
public static void main(String args[]) {
System.out.println(ObjectA.getInstance().getMessage());
}
}

Categories

Resources