I dont know how to really ask this.
But like...
Student stud1 = new Student("Shady");
Student stud2 = new Student("Nick");
Student stud3 = new Student("Name");
stud2.addBook(new Book(Book.BOOK_MISERABLES, 3););
Now if we assume we have the following variable in the Book class:
private Student owner;
And now the question, inside the constructor of "Book" -> Is it possible to get the "stud2" object it's being called to? Without adding an additional parameter to the constructor? If so, how? I think it's possible... So it will be something like this:
private Student owner;
public Book(int bookNum, int weeks){
this.owner = this.GET_THE_TARGET_THIS_IS_CALLED_ON;
this.bookNumber = bookNum;
this.time = weeks;
}
What you're asking is not directly possible. You will need to either
Pass a reference to the Student instance to your Book constructor
or
Use a setter inside the Book class to set the value of the owner field to your Student instance.
The latter would be a method that looks like this:
public void setOwner(Student owner) {
this.owner = owner;
}
Additionally, you may want to modify your Student.addBook method to call this setter, like this:
book.setOwner(this);
As you mentioned in your comment, you can traverse the stack using Thread.currentThread().getStackTrace() However, you'll be unable to obtain an object reference using that technique. You can obtain the class or method name but the uses for that are limited unless you intend to construct a new instance. That's all highly unorthodox and not at all appropriate for this situation.
Related
I am using java fx, nothing fancy in the code below, and catching the text field's focusedProperty to overwrite the newly entered value below. The code below changes a person's name that is entered in the textfield and when user clicks on cancel button it will put the old name back into the textfield. But for some reason a magic happens and whenever I set the person's name it overwrites the field in the cancelPerson variable. Could not figure out why this would happen? I get the cancelPerson from persons list before I set the new value. So how come changes in the persons list can affect an independent variable. Any idea why this would occur? Thanks.
private ObservableList<Person> persons;
private Person person;
private Person cancelPerson;
personName.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
final int index = personIdCombo.getSelectionModel().getSelectedIndex();
cancelPerson = persons.get(index);
final Person person = persons.get(index);
person.setName(personName.getText());
persons.set(index, person);
}
}
);
class Person{
private final StringProperty name;
public Person() {
this.name = new SimpleStringProperty("testName");
}
public SystemParams(Person person) {
this.name = person.name;
}
}
Jim Garrison's answer (suggesting the copy constructor) is correct; I
just wanted to add another answer to give a helpful way of thinking
about references in Java.
I found it helpful to think of an = assignment as a REFERS TO assignment. So, cancelPersons = persons.get(index); is basically saying:
cancelPerson REFERS TO persons.get(index);
Now, where your second line says final Person person = persons.get(index);, think of it as
final Person person REFERS TO persons.get(index);
See how they both REFER TO the same persons.get(index)? Now, whether you use cancelPerson or just person, Java is pointing back to the same overall object, not different ones.
Unless you have a new keyword somewhere, you are not actually creating a new object.
This is because person and cancelPerson are references and when you do
cancelPerson = persons.get(index);
final Person person = persons.get(index);
You end up with both variables pointing to the same object.
If you want to save a copy of person you have to do a "deep copy", that is create a new Person and copy the contents to the new object. This is usually done with what is referred to as a "copy constructor"
class Person {
public Person() { ... the no-arg constructor }
public Person(Person p) {
this.name = p.name;
... etc
}
}
In Java, class instances like instances of Person are reference types. This means that when you perform an assignment, you are merely copying a reference to an instance.
In your code, person and cancelPerson both refer to the same Person instance and any operations you do on them affect that same instance.
You could make a copy of a Person instance first if you don't want it to be modified.
My overall goal is to fill a Hashtable with employee data and be able to access/modify that data then print it out.
Given my Employee class here, can I use it like a struct in C? I'm trying to figure out how to initialize a Hashtable and fill it with this data but I'm sort of confused on how to implement it.
public class Employee {
private String empName;
private int empNum;
private String empJob;
public Employee(String empName, int empNum, String empJob)
{
this.empName = empName;
this.empNum = empNum;
this.empJob = empJob;
}
public int getEmpName()
{
return empName;
}
public String getEmpNum()
{
return empNum;
}
public String getEmpJob()
{
return empJob;
}
}
So, I tried this in main, using String as the key, so I want to use the names as the key so you can search by name. I'm also trying to manually fill it so I can test everything. Also, am I able to access say, the employee number on it's own? if so, how can I do this?
public class Main {
public static void main(String[] args)
{
Hashtable<String,Employee> EmployeeTable = new Hashtable<String,Employee>();
Employee Object = new Employee("Donald","Donald", 3, "Engineer");
}
}
Thanks in advance everyone!
You can add elements to your Hashtable using the put method. You just need to specify the key and the value.
Then you can retrieve values using the get method and specifying the key.
Example Usage:
Hashtable<String, Employee> table = new Hashtable<String, Employee>();
Employee bob = new Employee(...);
table.put("Bob", bob);
Then later you can say...
table.get("Bob");
and this will return Bob's Employee object for you.
Problems with your code:
There are a few problems with your code that you should be aware of.
1. Your Employee Constructor is wrong.
You've got a constructor for Product inside of your Employee class. This is illegal syntax and will not compile (I hope). Instead, you should use the Employee constructor.
2. Your Hashtable variable name matches the Object class.
You've named a variable Object. Object is the class that all java classes inherit from, so you really shouldn't name something this (if it even lets you at all).
The Object documentation mentions this...
Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.
3. Incorrect Hashtable types.
You've put the wrong types in your Hashtable declaration.
You wrote...
Hashtable<String, Employee> EmployeeTable = new Hashtable<String, Product>();
When really it should be...
Hashtable<String, Employee> employeeTable = new Hashtable<String, Employee>();
(Product changed to Employee)
(I also changed the variable to be lowercase)
Notes:
All of the documentation for Hashtable can be found here.
You may also be interested in using a HashMap instead of a Hashtable. They're almost identical but HashMap isn't threadsafe. You can see some of the differences here. If you really need a threadsafe map then I'd recommend ConcurrentHashMap, it's up to you to decide which one suits you the best though.
It's Java convention for variable names to start with lowercase letters. You don't have to follow this but it's definitely a good idea to. Syntax highlighters will no longer argue with you if you do.
What you want to achieve is rather this:
// Create my Hashtable using the diamond notation indicating to use the type arguments
// corresponding to the context which is <String, Employee> here
Map<String, Employee> EmployeeTable = new Hashtable<>();
Employee employee = new Employee("Donald", 3, "Engineer");
// put my employee into my map using empoyee's name as key
EmployeeTable.put(employee.getEmpName(), employee);
What you are looking for is Map#put(key, value)
After fixing several typo issues, your class Employee should be:
public class Employee {
...
public Employee(String empName, int empNum, String empJob)
{
...
}
public String getEmpName()
{
return empName;
}
public int getEmpNum()
{
return empNum;
}
...
}
NB: Hashtable is an outdated class, you should not use it anymore, if you don't intend to share it use an HashMap instead and if you want to share it use a ConcurrentHashMap
There are various things wrong with your class.
Example: the class is called Employee. Then the constructor must use that name, and nothing else!
So, it shouldn't read
public Product(String empName, int empNum, String empJob)
but
public Employee(String empName, int empNum, String empJob)
And then your call
Hashtable<String,Employee> EmployeeTable = new Hashtable<String,Product>();
could be correctly written down as
Hashtable<String,Employee> table = new Hashtable<>();
And no, a Hashtable is not a struct. A hashtable is a collection class; in other words: it is a Map. It maps a key (String in your case) to Employee objects.
But, well, stackoverflow is not a service where other people debug and explain your code to you. So, take my input as starting point; and for example: start reading the compiler messages.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am fairly new to Java proramming, as I have already stated in the title I want to pass some parameters that could or could not exist as instances of a class. If it does not exist, I want to create it. My code so far:
public class TestClass {
public static void main(String[] args) {
Person Ted = new Person();
Person Jack = new Person();
Item it = new Item(Ted);
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
}
}
public class Person {
public Person(){
//some code
}
}
public class Item {
public Item(Person name){
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
else{
//some code
}
void getItem(Person name){
System.out.println(name);
}
}
You misunderstand some things.
You can't use an identifier before it's been declared. The following is not correct in your code:
Item itSec = new Item (Pierce);
That's because you didn't declare Pierce before this line. You don't have to create an instance of the class, but you need a valid identifier. You should have declared it before this way:
Person Pierce;
At this moment the identifier, or the reference, is empty, so to say, or it is equal null. All object references which are not local are initiated this way, or they are equal false or 0, whichever is correct for their type. The result is the same as if you declared explicitly:
Person Pierce = null;
But let's move on. Say the reference has been declared. (Btw, Java uses camelCaseNotation for variables, so pierce would be correct.) Let's say we're at a point when Pierce is null or refers to some object, we don't know. Now we call this:
Item itSec = new Item (Pierce);
new Item(Pierce) calls the constructor public Item(Person name){...} in the class Item, which you should know. But now, in that constructor there's the line:
if(!(name instanceof Person)){
which you misuse. What this line is checking is not if the variable name equals null or an existing object, but variable type of name is a subtype of Person. Which will always return true in this place, as the function heading public Item(Person name){...} says this: the function is public, is a constructor, and the argument is of type Person (so Person or a subtype).
What you want to say here is this:
public Item(Person name){
if(name==null)){ //if the reference is empty
this.name = new Person(); //I'll explain this below
}
else{
this.name = name; //otherwise the local "name" will stay null
}
}
I used this.name and it was a jump ahead. Why? In your code that is Person name = ..., which is not correct as that name wouldn't last once the constructor's finished. You need a field in the Item class object, which will hold this value. So the Item class might be defined this way:
public class Item {
Person name;
//...
}
And now the field name holds the value assigned in the line:
this.name = new Person();
You need to use this to disambiguate which name you means. One is the Item class field, the other one is Person name the constructor parameter.
Now, we go back to the main function. If you want the variable Pierce to reference the newly created Person, this still needs to be done. The assignment can take place here, but first you'd have to create a function in the class Item that returns the value of its field name. So:
getName() {
return name;
}
And now call it from the main function:
Pierce = itSec.getName();
That's it. Finally, this function doesn't make sense:
void getItem(Person name){
System.out.println(name);
}
}
It doesn't get any Item. It only prints what you pass to it. And this doesn't mean that if you call it with getItem(Pierce), you will see "Pierce" on the screen. It will call the toString function in the object Pierce denotes, and as it is, you will get a standard object identifier. But if you define a function:
void printItem() {
System.out.println(name);
}
Then you can call it this way. For an existing object itSec:
itSec.printItem();
As for a getter function, it should return what you ask for, but that's another story.
What do you expect without instancing?
Person Pierce = new Person();
Item itSec = new Item (Pierce);
You cannot use a variable that does not exist...
Item itSec = new Item (Pierce);
The snippet above will never work because Pierce is undefined.
The code:
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
Does not really make any sense, because that is the same as calling
Person Ted = new Person();
Person Jack = new Person();
Wherein the Person instance does not actually contain any data (unless you have some magic going on when instantiating the Person!)
I assume what you really want to pass is not an object whose variable is the name of a person, but rather a Person object that contains the name of the person.
If so, your code should be like this:
Person p1 = new Person("Ted");
Person p2 = new Person("Jack");
If you really want to do some instantiation if something does not exist, you might be able to do something like this:
Item(String personName) {
if(isExisting(personName)) {
getPerson(personName);
} else {
Person p = new Person(personName);
}
boolean isExisting(String personName) {
// Check if person exists somewhere
}
Person getPerson(String personName) {
// Retrieve the Person instance with the same person name.
}
if(!(name instanceof Person)){
Person name = new Person();
}
is meaning less because 'name' is always object is instance of person in this situation..
Item itSec = new Item (Pierce);
Pierce is not an object.. We can pass only Person object to constructor of Item class.. There is no any method to create an object of any class by just passing unkown variable..
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
If it does not exist, I want to create it.
There's no "if" about it. The code never declared that variable, so it will never exist. (And never compile in its current state. Surely your Java compiler is telling you this.) Given that it always needs to be created, just create it:
Person Pierce = new Person();
Item itSec = new Item(Pierce);
Edit: Based on ongoing comments, it sounds like you want to have something more like a Map. Consider an example:
Map<String,Person> people = new HashMap<String,Person>();
people.put("Pierce", new Person());
The Map would basically be a collection of key/value pairs where the name is the key and the Person is the value. You can dynamically add/edit/remove elements to the collection as you see fit.
Then to use it, you'd call another operation on the map:
Item itSec = new Item(people.get("Pierce"));
You could use various operations to check if a value exists in the collection, add it, etc. You might even extend the class to add your own operations which create one if it doesn't exist when trying to get it.
Java won't dynamically create variables for you if a variable doesn't exist, but operations on a Map (or potentially other similar structures) can check if an element exists, add it, remove it, etc.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Im a new programmer and I want to know when its best practice to use overloaded constructors and what makes it different from single primary constructor.
The short answer is: you should use overloading whenever you need it.
As a real-life example, take a look at the JLabel API: https://docs.oracle.com/javase/8/docs/api/javax/swing/JLabel.html
JLabel has quite a few constructors: one that just takes a String, one that takes a String and an icon, one that only takes an icon, and one that doesn't take any arguments at all.
You would use each constructor when you want to construct that kind of JLabel: one that displays a String, one that displays a String and an icon, one that only displays an icon, or one that doesn't display anything yet (until you call one of its setter functions).
Constructor overloading is useful when you want to allow user to create objects in multiple different ways.For example to be able to create a simple Student class object in following different ways:
new Student(45); // given student id
new Student("name"); // given student name
new Student(45,"name"); // given student registration id and name
This helps ease the task of creating objects according to our requirements. You can link this concept with various java API's as the provide a no of different ways to initialize an object of a class.
Also you can combine the Construstor Overloading with Constructor chaining.
Here is an examlple:
public Student (int id){
this(id,"ANY-DEFAULT-NAME"); // calls the constructor of same class with 2 params
}
public Student (String name){
this(ANY-DEFAULT-ID,name);// calls the constructor of same class with 2 params
}
public Student (int id,String name){
// here you can initialize the instance variables of the class.
}
You can overload a constructor based in your needs. For example,let's say that you have a simple class called Dog, that have some attributes like: Name,Breed, Birthday, Owner and skin color.
public class Dog {
private String name;
private String breed;
private Date birthday;
private String owner;
private String skinColor;
/*Getters and Setters*/
...
}
If you instance a object of type Dog and want to set a all or some of the attributes' values, you'll have to call all the setters methods of the object, but with the constructor, you can save that step passing the values directly every moment you instance the object.
Example:
public class Dog {
private String name;
private String breed;
private Date birthday;
private String owner;
private String skinColor;
public Dog(String name, String breed,Date birthday,String owner,String skinColor){
this.name = name;
this.breed = breed;
this.birthday = birthday;
this.owner = owner;
this.skinColor = skinColor;
}
/*Getters and Setters*/
...
}
Dog myDog = new Dog("Jose", "Chiguagua",new Date(),"Jhon","Brown");
If you want only instance the object with the name only, you can do it too. A good practice is, if you have an object with attributes that is necessary to fill in some point, provide the default constructor, if you do not provide it, you will always need to pass some values for instance a object. This give flexibility to the programmer.
How can I do such a thing?
String N = jTextField0.getText();
MyClass (N) = new Myclass();
Is it even possibe?
Or as my question's explains, how can I just make a method to create a new object of my specified class just with a different name each time I call it.
I really searched everywhere with no luck.
Thanks in Advance
P.S.
I wish you guys can excuse me for not being clear enough, Just to say it as it is, I made a textfield to get the name of someone who wants to make an account, and I made a class named "Customer". and a button named "Add". Now I want every time "Add" is clicked, compiler take what is in my textfield and make an object of the class "Customer" named with what it took from the textfield
It was too hard to read it in comments so I updated my question again, so sorry.
I'm stuck so bad. I suppose my problem is that I didn't "understand" what you did and only tried to copy it. This is what I wrote:
private void AddB0MouseClicked(java.awt.event.MouseEvent evt) {
String name = NameT0.getText();
Customer instance = new Customer(Name);
Customer.customers.add(instance);
and this is my Customer class:
public class Customer{
String name;
public Customer(String name){
this.name = name;
}
public String getName(){
return name;
}
static ArrayList<Customer> customers = new ArrayList<Customer>();
Variable names must be determined at compile time, they are not even part of the generated code. So there is no way to do that.
If you want to be able to give your objects names, you can use
Map<String, MyClass> map = new HashMap<>();
Add objects to the map like this (e.g):
map.put(userInput, new MyClass());
and retrieve objects like this:
MyClass mc = map.get(userInput);
I'm not entirely sure what you mean by...
how can I just make a method to create a new object of my specified
class just with a different name each time I call it
...but if I'm interpreting you correctly, I believe what you're trying to do as make MyClass accept a constructor parameter. You can do:
public class MyClass {
private String name;
public MyClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Then to create a new instance of MyClass, do:
String name = jTextField0.getText();
MyClass instance = new MyClass(name);
instance.getName(); // returns the name it was given
EDIT
Since you've added clarifications in the comments since I first answered this question, I thought I would update the answer to portray more of the functionality that you're looking for.
To keep track of the MyClass instances, you can add them to an ArrayList. ArrayList objects can be instantiated as follows:
ArrayList<MyClass> customers = new ArrayList<MyClass>();
Then for each MyClass instance you wish to add, do the following:
customers.add(instance);
Note that the ArrayList should not be reinstantiated for each instance that you wish to add; you should only instantiate the ArrayList once.