Originally Posted by
Format
Actually yeh your right
, Serialization would be alot better, so why not go ahead and do it?
:l
If you think this is bad, go gf yaself. atleast i tried
Creating a Serializable Class
First you need to know how to make a serializable class, so let's do that now
Code:
import java.io.Serializable;
@SuppressWarnings("serial")
public class SerializedClass implements Serializable {
public SerializedClass() {
// the constructor
}
}
So now u have a pretty basic Serializable class that can be used various ways. The constructor here isn't necessary because by default it's already made public, but it's there just to show you what a constructor is if you dont know how one is made, haha.
Transient Variables
When you define a variable, it typically isn't static or final unless it needs to be such as something you'll use on a global level. You also have another option here and that's making a variable transient, which basically means the variable will be overlooked when saving it, so if the player logs out the variable resets. Can be very good in some cases. Here's how you define it:
Code:
private transient int someVar;
Go you can now put this in the file like so:
Code:
import java.io.Serializable;
@SuppressWarnings("serial")
public class SerializedClass implements Serializable {
private transient int someVar;
public SerializedClass() {
// the constructor
}
}
Creating an Instance
So now that you have a class with a variable, we;re going to create an instance of this that will allow us to modify the variable in a non-static way. First, we need to create an instance to this class like so:
Code:
SerializedClass sc = new SerializedClass();
This will create a new instance of the class, and all variables in the class are always the default (undefined variables are always null if its a string, 0 if its an integer, false if it's a boolean) unless it's defined specifically.
Now since you've probably noticed that the "someVar" is private, we wont be able to use it outside of the class it's defined in. So we now need a getter and setter that can set the variable from the created instance about:
Code:
public int getSomeVar() {
return someVar;
}
public void setSomeVar(int aNumber) {
this.someVar = aNumber;
}
now we can modify the "someVar" variable like so:
Code:
SerializedClass sc = new SerializedClass();
sc.setSomeVar(10);
System.out.println(sc.getSomeVar());
This will output "10" in the console. So why not make it public and access it directly and save a few lines? Because I'm trying to teach a little bit of OOP in the process secretly >.>
Anyway, if you need to know more about OOP, here's a good place to start Lesson: Object-Oriented Programming Concepts (The Java™ Tutorials > Learning the Java Language)
We can also modify "someVar" by adding an argument to the constructor like so:
Code:
public SerializedClass(int aNumber) {
this.someVar = aNumber;
}
Doing it this way is if you need to initialize the variable to a specific value, such as if you need to identify what to do in the script. Here's how you would use this:
Code:
SerializedClass sc = new SerializedClass(10);
System.out.println(sc.getSomeVar());
Storing the data
So now we need to store the data. If you're referencing the class from another that is already being stored this does not need to be done, as it's already being stored alongside the class that is. I have written a simple methods to make storing it easy:
Code:
public void save() {
try {
File file = new File("path/to/the/file.ser");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
out.writeObject(this);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Using this we can store the file to the specified path with a .ser extension. So after we set the "someVar" variable we can then save it to a .ser file AFTER removing the transient modifier. If you don't remove the transient modifier, the variable will not save, so now we have this in total:
Code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
@SuppressWarnings("serial")
public class SerializedClass implements Serializable {
/**
* Notice the lack of "transient"
*/
private int someVar;
/**
* A basic constructor, not necessary because the constructor is defined public by default
*/
public SerializedClass() {
// the constructor
}
/**
* A constructor that initializes the someVar to the specified number
* @param aNumber
*/
public SerializedClass(int aNumber) {
this.someVar = aNumber;
}
/**
* @return the value of someVar
*/
public int getSomeVar() {
return someVar;
}
/**
* Sets the value of someVar
* @param aNumber the number you wish to set someVar to
*/
public void setSomeVar(int aNumber) {
this.someVar = aNumber;
}
/**
* Saves the instance of this class to the specified path by creating a new
* File object and defining the path and file name.
*/
public void save() {
try {
File file = new File("path/to/the/file.s");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
out.writeObject(this);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now after we set someVar, we can then save the data:
Code:
SerializedClass sc = new SerializedClass();
sc.setSomeVar(50);
sc.save();
OR
SerializedClass sc = new SerializedClass(50);
sc.save();
Loading the Data
Now that we have some data saved to a file, we can then load it using the method below:
Code:
public static final SerializedClass loadFile() {
File file = new File("path/to/the/file.s");
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))) {
SerializedClass object = (SerializedClass) in.readObject();
return (SerializedClass) object;
} catch (Exception e) {
return null;
}
}
this is called in a static manner because we need to call this method directly. No point in making a new instance of the class then loading data, just doesnt work that way haha. Anyway, we load the data like so:
Code:
SerializedClass sc = SerializedClass.loadFile();
System.out.println(sc.getSomeVar());
Casting it over to Serialized class is necessary in the loadFile method because you cannot convert from an Object to SerializedClass. So we tell java essentially that this sould be returned as SerializedClass, and not object, and also it doesn't have to be done in the code later on down the road.
You might have also noticed the lack on closing the ObjectInputStream as well, this is because I've wrapped the ObjectInputStream in what is know is an AutoCloseable try statement, meaning once the resource is done being used it's automatically closed.
Useful Resources:
Lesson: Object-Oriented Programming Concepts (The Java™ Tutorials > Learning the Java Language)
The try-with-resources Statement (The Java™ Tutorials > Essential Classes > Exceptions)
Serializable (Java Platform SE 7 )
ObjectOutputStream (Java Platform SE 7 )
FileOutputStream (Java Platform SE 7 )
File (Java Platform SE 7 )
Java Object Serialization Specification: 1 - System Architecture
tired of typing, done now =.=