so im trying to figure out how to add fields to a class in java? e.g i have a program, a user and it has this class : public class Person { String firstName; String lastName; now my user would like to permanently add the age to the class Person so that it looks like this: public class Person { String firstName; String lastName; int age; how do i do it?
well any ways ill assume the latter for now. Use a Map<String, Object> the string will be the name and the object is what ever object data you want example would be Map<String, Object> map=new HashMap<String, Object> (); map.push(Age, new Integer(2)) Using a flat file database like sqlite to save data as a flat file database would be a great way to save data or idk use a csv.
@Needhydra's way works if you need to add age on-the-fly. If you know before compiling that age is an optional parameter, you could try overloading your constructor. So, in your Person class, you have two constructors and the related variables declared and get and set methods: Code: public Person (String firstNameIn, String lastNameIn) { setFirstName(firstNameIn); setLastName(lastNameIn); } public Person (String firstNameIn, String lastNameIn, int ageIn) { setFirstName(firstNameIn); setLastName(lastNameIn); setAge(ageIn); } Then in your main, you can choose between the two depending on what parameters are required. Code: Person person1 = new Person("Bob", "Smith", 23); Person person2 = new Person("Barbara", "Doe"); You can also use the setAge method on either. Here are two classes that will accomplish this for you: Code: public class Person { private String firstName, lastName; private int age; //Default constructor public Person() { } //Constructor without age public Person(String firstNameIn, String lastNameIn) { setFirstName(firstNameIn); setLastName(lastNameIn); } //Overloaded constructor with age public Person(String firstNameIn, String lastNameIn, int ageIn) { setFirstName(firstNameIn); setLastName(lastNameIn); setAge(ageIn); } //Get and set methods. If you're going to really use this, add error checking. public String getFirstName() { return firstName; } public void setFirstName(String firstNameIn) { firstName = firstNameIn; } public String getLastName() { return lastName; } public void setLastName(String lastNameIn) { lastName = lastNameIn; } public int getAge() { return age; } public void setAge(int ageIn) { age = ageIn; } } Code: public class Main extends Person{ public static void main(String[] args) { // Use two different overloaded constructors with age as an optional parameter. Person person1 = new Person("Bob", "Smith"); Person person2 = new Person("Barbara", "Doe", 32); //Add age to person1 even though it wasn't part of the constructor. person1.setAge(22); //Now person1 has an age. System.out.printf("%s is %d.", person1.getFirstName(), person1.getAge()); } }
you cant add variables after the program is complied so you need a map that can assign a "variable" name and some kind of data to it. you need to write a bunch of cases to deal with all the different data types. you also need to have a file somewhere in order to load from to save the data structure in the map
To add to @Needhydra, Java is a compiled language. Once you compile your source into binary, what's there is there, and what's not is not. You can't retroactively add a variable to a program without updating your source and recompiling. You can try your luck with lists, linked lists, array lists, and maps, but they're more like duct taped solutions for your usecase.
Reflection is a thing. Don't specifically know how to do it in Java, but it is possible in C#, so I imagine you could do the same thing in Java too.
Reflection can be used, but I'd recommend against it if you only want to permanently add a single class variable. Reflection is more useful for dynamically generating a class at runtime based on the system that's running it or on factors that you can't account for directly in your code. You can also look at using BCEL or Byte Buddy. I'm still of the opinion that if you only want to add a single variable, your best bet is to just update your code and recompile it.
k i got it to work which is nice ... but i dont think its really efficient if i want to expand my code and do the same with 70 other classes....
Sounds like you should use a database and gave 1 class that can process the data. Or dev a web app so when ever a user breaks something you can fix it quickly.
True, but I'm not about to make any assumption about his case. I mentioned reflection because it sounds like that's what he wants. As for what he actually needs, that's another matter entirely. Besides, I doubt he'd actually use reflection just to add a single variable that he knows beforehand. Nobody does that.
For reference, if the OP wants to use reflection in Java to execute runtime injection for his stated case, he'd need to create a class that runs premain and creates a sub of whatever class he wants to modify. Then, he'd have to run a proxy in his main that redirects any calls to the super to the sub. Also, he'd have to build the variables and methods for the sub line-by-line with reflection and either bytecode or something like Byte Buddy. It's non-trivial, and in most cases, it adds unneeded complexity to your code. To be sure, there are some great uses, like security checks or loading modules on-demand, but the case described by the OP doesn't fall into the categories that are generally useful with runtime injection. A lot of people come at Java like they'd approach JS or Python, where it's basically trivial to manipulate your code at runtime. I'm going to go out on a limb and assume that's what the OP was hoping for here.
Reflection is built into Java, too. It's just not really made for runtime injection. Instead, it's more useful for things like enumerating get and set methods in a binary or Spring serverlets for which there is no available documentation.
Oh. Well, I've to admit that even though System.Reflection can be used to build custom types at runtime, I've never actually used it. Just haven't been in a situation where I have to use it. So I guess it's fine even if Java doesn't have it. I suppose it's just not in their priority list.