I have an Object Human:
public class Human {
String name;
public Human(String name){
this.name = name;
}
}
In my main Class I have an instance of this human "John".
With a function called getVarOfObject() I want to get John's name:
public class Example {
public static Object getVarOfObject(Object obj, Object var){
return obj.var;
}
public static void main(String[] args) {
Human john = new Human("John");
String johnsName = getVarOfObject(john, name);
}
}
I know you could just type john.name but in my case I need to have a function which can do this.
You can use this code
Field field = <Your object>.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (String) field.get(object);
You can't do this except reflectively.
Please note that this wizardry can lead to errors, subtle issues, exceptions, performance losses, asphyxiation, drowning, death, paralysis, or fire.
Object obj is the object, and String field is the name of the field.
Class clazz=Human.getClass(); //or for class-independence use `obj.getClass()`.
Field fd=clazz.getField(name);
fd.get(obj);
Why don't you use accessor methods (getters and setters)?
In Human:
public String getName() {
return name;
}
and in your main method:
Human john = new Human("John");
String johnsName = john.getName();
Related
Lets say I have a class
class A {
string name;
int age;
string gender;
//assuming all the constructors, getters and setters are present
}
for purpose of simplicity, lets assume all these members are public and to access them I create an object of that class as follows
A a = new A();
is there a way to access the each member as follows
String string = "age"
a.string
and get the age of the object and so on.
similarly, lets say I have a getter and can I access it using
String string = "getAge()";
a.string;
I am an beginner java programmer trying to optimize a code written in swift (needless to say I am a novice in swift), which has a class with more than 50 members and setting/getting each of them in some other module gets very tedious.
Just wondering if this is possible in either of the programming languages. In java I assume something like this might be possible using class reflection, but not very sure.
Well, you can use reflection, and do something like:
A a = new A();
Class cls = a.getClass();
//read a method value
String methodName = "getAge";
Method method = cls.getDeclaredMethod(methodName);
int methodReturnedResult = method.invoke(a, null);
//read a field value
String fieldName = "age";
Field field = cls.getDeclaredField(fieldName);
int fieldValue = field.get(a);
This is another example
Java Reflection tutorial
Though it is important to note that reflection wasn't meant for these cases and it isn't considered a good design to use reflection in these scenarios. What you need to do is to use IDE's abilities to generate setters and getters for you automatically.
Which IDE do you use? Most Java IDE's has the ability to generate getters and setters automatically according to the class fields.
This is how you do it in Eclipse, Netbeans, Intellij and in Android Studio.
As explained here (with an example), you can use java reflection to check whether class contains a field and get the value of that field.
Also, making the fields public isn't a good idea, they should be private and accessed only via getters and setters.
If you have to use reflation, below should work.
Class A
class A {
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Utility method in your class
public Object get(String methodName, A a) throws Exception {
Object ret = null;
if(a != null){
Class<A> cl = A.class;
Method method = cl.getDeclaredMethod(methodName);
ret = method.invoke(a);
}
return ret;
}
public void set(String methodName, Object value, A a) throws Exception{
Class<A> cl = A.class;
Method method = cl.getDeclaredMethod(methodName, value.getClass());
method.invoke(a, value);
}
Test it
public void testIt() throws Exception{
A a = new A();
set("setName", "xyz", a);
String name = (String) get("getName",a);
System.out.println(name);
}
Note: be careful on boxed type i.e. int is represented as Integer. And good amount of null checks.
package book1;
import java.util.ArrayList;
public abstract class Book {
public String Book (String name, String ref_num, int owned_copies, int loaned_copies ){
return;
}
}
class Fiction extends Book{
public Fiction(String name, String ref_num, int owned_copies, String author) {
}
}
at the moment when i input values into the variable arguments and call them with this :
public static class BookTest {
public static void main(String[] args) {
ArrayList<Book> library = new ArrayList<Book>();
library.add(new Fiction("The Saga of An Aga","F001",3,"A.Stove"));
library.add(new Fiction("Dangerous Cliffs","F002",4,"Eileen Dover"));
for (Book b: library) System.out.println(b);
System.out.println();
}
}
i get a return value of this:
book1.Fiction#15db9742
book1.Fiction#6d06d69c
book1.NonFiction#7852e922
book1.ReferenceBook#4e25154f
how can i convert the classes to return a string value instead of the object value? I need to do this without changing BookTest class. I know i need to use to string to convert the values. but i don't know how to catch the return value with it. could someone please point me in the right direction on how to convert this output into a string value?
You need to overwrite the toString() Method of your Book class. In this class you can generate a String however you like. Example:
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.author).append(": ").append(this.title);
return sb.toString();
}
You need to override the toString() method in your Book or Fiction class. The method is actually declared in the Object class, which all classes inherit from.
#Override
public String toString(){
return ""; // Replace this String with the variables or String literals that you want to return and print.
}
This method is called by System.out.println() and System.out.print() when they receive an object in the parameter (as opposed to a primitive, such as int and float).
To reference the variables in the method, you'll need to declare them in the class and store them via the class's constructor.
For example:
public abstract class Book {
private String name;
private String reference;
private int ownedCopies;
private int loanedCopies;
public Book (String name, String reference, int ownedCopies, int loanedCopies) {
this.name = name;
this.reference = reference;
this.ownedCopies = ownedCopies;
this.loanedCopies = loanedCopies;
}
#Override
public String toString(){
return name + ", Ref:" + reference + ", OwnedCopies: " + ownedCopies + ", LoanedCopies: " + loanedCopies; // Replace this String with the variables or String literals that you want to return and print.
}
}
The classes you have defined, don't store any values. It is in other words useful to construct a new book. You need to provide fields:
public abstract class Book {
private String name;
private String ref_num;
private int owned_copies;
private int loaned_copies;
public String Book (String name, String ref_num, int owned_copies, int loaned_copies) {
this.name = name;
this.ref_num = ref_num;
this.owned_copies = owned_copies;
this.loaned_copies = loaned_copies;
}
public String getName () {
return name;
}
//other getters
}
Now an object is basically a set of fields. If you want to print something, you can access and print one of these fields, for instance:
for (Book b: library) System.out.println(b.getName());
In Java, you can also provide a default way to print an object by overriding the toString method:
#Override
public String toString () {
return ref_num+" "+name;
}
in the Book class.
Need to give your object Book a ToString() override.
http://www.javapractices.com/topic/TopicAction.do?Id=55
Example:
#Override public String toString()
{
return name;
}
Where name, is a string in the Class.
I am hoping that you have assigned the passed arguments to certain attributes of the classes. Now, once you are done with that, you can override the toString() method in Book to return your customized string for printing.
If we create a String like below and print the value:
String s=new String("demo");
System.out.println(s);
...the output is:
demo
Good. This is the expected output. But here String is a class. Remember that. Below is another example. For example, take a class like this:
class A
{
public static void main (String args[])
{
A a =new A();
A a1=new A("hi"); //we should create a Constructor like A(String name)
System.out.println(a1); //here O/P is address
}
}
My doubt is that I created the A instance in the same way I created the new String object, and I printed that object. So why does it not print the given String for the instance of A?
You need to override the Object#toString() in your class. By default, the toString() method of Object is called.
Also, to print the value, you just need to override the method as internally a call will be made to the toString() method when this statement is executed.
System.out.println(a1);
Sample overriden toString() method.
#Override
public String toString() {
// return a string value
return "The String representation of your class, as per your needs";
}
You have to override toString() method in your class the way you want to print something when call System.out.println();. In String class toString() method has override and you will get out put above due to that.
As pointed out already, you need to override the default toString() method inherited from the Object class. Every class automatically extends the Object class, which has a rather simple toString(), which can't know how to turn your particular object into a String. Why should it, especially if your class is arbitrarily complex? How is it supposed to know how to turn all your class's fields into a "sensible" string representation?
In the toString() of your class, you need to return the string that you want to represent your class with. Here is a simple example:
class A {
String foo;
public A(String foo) {
this.foo = foo;
}
public String toString() {
return foo;
}
}
public class sample {
public static void main(String[] args) {
A a = new A("Hello world!");
System.out.println(a);
}
}
String is a class whose purpose is to hold a string value and will return that value if referenced. When you use other classes, you will usually want to add other behavior. If you want to use the class to hold different values that you can set (on object creation or later in processing) you may want to use "setter" and "getter" methods for such values.
Here is an example:
public class Snippet {
private static final String C_DEFAULT_VALUE = "<default value>";
private String name;
private static Snippet mySnippet;
public Snippet() {
}
public Snippet(String value) {
setName(value);
}
/**
* #param args
*/
public static void main(String[] args) {
if (args != null && args.length > 0) {
mySnippet = new Snippet(args[0]);
} else {
mySnippet = new Snippet(C_DEFAULT_VALUE);
}
System.out.println(mySnippet.getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Person {
String name = “No name";
public Person(String nm) { name = nm; }
}
class Employee extends Person {
String emplD = “0000”;
public Employee(String id) { empID = id; }
}
public class EmployeeTest {
public static void main(String[ ] args)
{
Employee e = new Employee(”4321”);
System.out.println(e.empID);
}
}
The constructor of Employee must call its super constructor, the constructor of Person.
public class Person
{
private String name;
public Person(String nm)
{
this.name = nm;
}
public String getName()
{
return this.name;
}
}
public class Employee extends Person
{
private String emplD;
public Employee(String nm, String id)
{
super(nm);
this.empID = id;
}
public String getId()
{
return this.empID;
}
}
public class EmployeeTest
{
public static void main(String[] args)
{
Employee e = new Employee("Some Name", "4321");
System.out.println(e.getID());
}
}
Change “No name’ into “No name" (closing quotes)
Maybe it's here:
String name = “No name’;
should it be:
String name = "No name";
Also, I'm not sure if this is the editor that you've pasted it in from doing this, but this is wrong too:
Employee e = new Employee(”4321”);
should be:
Employee e = new Employee("4321");
A number of things:
You're using the wrong kind of quote characters around your strings. You need to use ". Not “, ', or ”.
Your Person class has no default constructor. Because of this you must explicitly call super("some name"); as the first line of your Employee constructor (I would suggest adding a constructor that takes both name and employeeId as parameters).
You declared the property as emplD (with a lower-case L character), but you try to assign to it as empID (with an uppercase I character). You can call it whatever you want, but the name needs to match in both places.
Your object design violates the basic principles of encapsulation. The name and empID properties should be private fields, and if external classes need access to these values, then you should provide the appropriate public getter methods. In other words, instead of e.empID you should be able to say e.getEmpID().
It is generally not good coding style to define multiple classes in a single file, particularly when all of them are meant to be publicly accessible.
Change this line
String name = “No name’;
to:
String name = “No name";
check your closing qoutes.
Your empID field is not public / there is no accessor method for it / it is not defined as a property. Also don't expect people to help if you provide absolutely no information on the error other than the source code and a vague post title.
You have to call the constructor of the superclass (Person) in the constructor of the class `Employeesuper(id); Please find the correct code below.
public Employee(String id) {super(id);empID =id;
Calling a super class constructor would fix the issue !
public class Person {
String name = "No name";
public Person(String nm) { name = nm; }
}
public class Employee extends Person {
String empID = "0000";
public Employee(String id) {
super("Some Name");
empID = id; }
}
public class EmployeeTest {
public static void main(String[] args){
Employee e = new Employee("4321");
System.out.println(e.empID);
}
}
Hi i have the following code:
public List<Person> findAll() {
List<Person> copy = new ArrayList<Person>();
for (Person person : personer) {
copy.add(person);
}
return copy;
}
But when i test this i only retrieve the following and not the value:
[Person#15c7850, Person#1ded0fd,
Person#16a9d42]
How do i get the values and not like above. Where i am inserting the person the code looks like this:
public boolean insert(String name, String nbr) {
if (containsName(name)) {
return false;
}
Person person = new Person(name, nbr);
personer.add(person);
return true;
}
and here is my Person class:
class Person {
private String name;
private String nbr;
public Person (String name, String nbr) {
this.name = name;
this.nbr = nbr;
}
public String getName() {
return name;
}
public String getNumber() {
return nbr;
}
}
You're already receiving the objects you want.
What you see is an internal representation of these objects.
You must iterate through them and call their respective methods to see the information you probably want to see.
If you're not satisfied with these results, you must override toString to provide you with more meaningful information.
Update:
after seeing your edit, you should add toString similar to this one in your Person class:
#Override
public String toString() {
return "Name: " + name + ", number: " + nbr;
}
By the way, you're storing nbr as a string, and it's obvious it should be an integer. So, I'd suggest changing its type to an int or Integer.
You are getting a List object back. You can use the Person object to get the data that you need. To get to the Person objects, iterate over the list.
List<Person> people = findAll();
for Person p : people {
String phoneNumber = p.phoneNumber();
String name = p.Name();
}
Override the toString() method in the Person class if you want a better description when printing the results.
Put something like this in the class Person (don't change the method name!):
public String toString() {
return name;//change this line
}
You are printing out an Object that has the default toString inherited from the Object class. This will print out the type of object it is and its location in memory (ie: Person#1ded0fd).
If you'd like it to see something else, you can override the toString method within your class:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public String toString() {
return this.name;
}
}
If your class looked like the above, this would allow you to do something like this:
Person p = new Person("John");
System.out.println(p);
> John
You can also just grab it as is and print out any information you want from it without overriding the toString method.
Person p = new Person("John");
System.out.println(p.getName());
> John
What value or class Person's property you aspect to retrieve from the ArrayList? This kind of value(Person#15c7850, etc) shows that the Person's object random id that assigned by JVM when you use
System.out.print(copy).