Serialization in java


package moc.em.mygdxgame;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;

public class Player implements Serializable {

	/**
	 * The "Serializable" interface is a class that lets you "read" or "write" 
	 * the object on to the disk, The TextureRegion is to show a certain area inside a sprite sheet
	 * Some of the objects which was initialized in this class is not serializable, so we can only save certain data
	 * 
	 */
	
	private static final long serialVersionUID = 1L;
	private String file;
	private Vector2 position;
	private static final int column = 4;
	private static final int row = 4;
	private transient Animation animation;
	private transient Texture texture;
	private transient TextureRegion[] frame;
	private static final String saveFile = "player.dat";
	private float stateTime;
	private transient TextureRegion currentFrame;
	private Rectangle bounds;
	
	public Player(String file, Vector2 position){
		this.file = file;
		this.position = new Vector2(position);
		texture = new Texture(Gdx.files.internal(file));
		TextureRegion[][] tr = TextureRegion.split(texture, texture.getWidth()/column, texture.getHeight()/row);
		frame = new TextureRegion[column * row];
		
		int index = 0;
		for(int i = 0; i < row; i++){
			for(int j = 0; j < column; j++){
				frame[index++] = tr[i][j]; // did not know you can have the index do that inside an array "index++"
			}
		}
		animation = new Animation(1,frame);
		stateTime = 0f;
		currentFrame = animation.getKeyFrame(0);
		bounds = new Rectangle(position.x, position.y, currentFrame.getRegionWidth(), currentFrame.getRegionHeight());

	}
		
	@SuppressWarnings("unused")
    private static byte[] serialize(Object obj) throws IOException {//This method converts an object to a byte array
            ByteArrayOutputStream b = new ByteArrayOutputStream();
            ObjectOutputStream o = new ObjectOutputStream(b);
            o.writeObject(obj);
            o.flush();
            return b.toByteArray();
    }
   
    public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {//This converts byte array to an object
            ByteArrayInputStream b = new ByteArrayInputStream(bytes);
            ObjectInputStream o = new ObjectInputStream(b);
            return o.readObject();
    }	
	
	public static void savePlayer(Player player) throws IOException {
		FileHandle fh = Gdx.files.local(saveFile); //relative path
		OutputStream out = null;
        try {
            fh.writeBytes(serialize(player), false); //It is a byte array :)
        }catch(Exception e){
            System.out.println(e.toString());
        }finally{
            if(out != null) {
            	try{
            		out.close();
            	} catch (Exception ex){}
            }
        }
   
    System.out.println("Saving Player");
	}
	
	public static Player loadPlayer() throws IOException, ClassNotFoundException {
        Player player = null;
        FileHandle fh = Gdx.files.local("player.dat");
        player = (Player) deserialize(fh.readBytes()); // Its an object again :)
        return player;
    }
    
	public void update(){
		bounds.set(position.x, position.y, currentFrame.getRegionWidth(), currentFrame.getRegionHeight());
		if(stateTime < 4){
			stateTime += Gdx.graphics.getDeltaTime();
		} else {
			stateTime = 0;
		}
		if(Gdx.input.isKeyPressed(Keys.W)){
			position.y += 1f;
			currentFrame = animation.getKeyFrame(12 + stateTime);
		} else if(Gdx.input.isKeyPressed(Keys.A)){
			position.x -= 1f;
			currentFrame = animation.getKeyFrame(4 + stateTime);
		} else if(Gdx.input.isKeyPressed(Keys.S)){
			position.y -= 1f;
			currentFrame = animation.getKeyFrame(0 + stateTime);
		} else if(Gdx.input.isKeyPressed(Keys.D)){
			position.x += 1f;
			currentFrame = animation.getKeyFrame(8 + stateTime);
		}
	}
	
	public void draw(SpriteBatch sb){
		sb.draw(currentFrame, position.x, position.y);
	}	
	public String getPlayerImage(){
		return file;
	}
	
	public Texture getTexture(){
		return texture;
	}
	
	public Vector2 getPosition(){
		return position;
	}
		
	public void changePlayer(String file){
		this.file = file;
	}
	
	public Animation getAnimation() {
		return animation;
	}

	public void setAnimation(Animation animation) {
		this.animation = animation;
	}

	public TextureRegion[] getFrame() {
		return frame;
	}

	public void setFrame(TextureRegion[] frame) {
		this.frame = frame;
	}

	public TextureRegion getCurrentFrame() {
		return currentFrame;
	}

	public void setCurrentFrame(TextureRegion currentFrame) {
		this.currentFrame = currentFrame;
	}

	public float getStateTime() {
		return stateTime;
	}

	public void setStateTime(float stateTime) {
		this.stateTime = stateTime;
	}		
    public String getFile() {
		return file;
	}

	public void setFile(String file) {
		this.file = file;
	}

	public Rectangle getBounds() {
		return bounds;
	}

	public void setBounds(Rectangle bounds) {
		this.bounds = bounds;
	}
}

So I have three classes which are not serialize. Which are the: TextureRegion, Texture, and Animation class. I am trying to find a way to save the entire player class. I cannot use transient, because There is a render method in another class which always calls the update method. I would get a nullpointer from “bounds.set(position.x, position.y, currentFrame.getRegionWidth(), currentFrame.getRegionHeight());” If I use transient.