Gregory Weir's answer is my favorite for how to structure the item instances in order to perform multiple roles.
To load from a file:
First, use YAML. YAML is a featureful data description language; it can be parsed relatively quickly, read and edited by humans, supports binary data, and libraries exist for most programming languages, including Java. This solves the "how do I get data from files into objects?"
Second, use the flyweight pattern. Most of the data you read from those files is static. It's not going to change per instance ("axe does 1d10 base damage and breaks wood but not stone" - that's true of all five axes a player has). What you actually read from the YAML files are these platonic definition, and your individual item instances have unowned (and constant) references to these, along with per-instance data like "How many swings before I break?", "Did the player give me a custom name?", and so on.
By sharing the cross-instance data in a single object, you preserve lots of memory, and make it easy to update items without persisted game state (save games or player database).
So your class structure looks something like:
- class Item - One instance per item
- Owns-a Weapon instance
- Owns-a Tool instance
- Has-a custom name, etc.
- class Weapon - (Up to) one instance per item
- Is-a ItemComponent
- Refers-to WeaponDef
- Has-a bonus enchantment level, etc.
- class Tool - (Up to) one instance per item
- Is-a ItemComponent
- Refers-to ToolDef
- Has-a durability, etc.
- class WeaponDef - One instance per kind of weapon
- Read from a file, fields should be constant.
- Has-a base damage amount, 1 or 2 hands, etc.
- class ToolDef - One instance per kind of tool
- Read from a file, fields should be constant.
- Has-a base durability, materials it can break, etc.