Above all, code. Code lots. And reflect on it. That's how you learn to value other things, because you feel the pain that leads to a motivation for a solution. While doing that:
- Work with other people on projects
- Learn from people better than you and be humble
- Learn to value the parts that are not strictly coding but rather help with quality
- Get perspective from other programming paradigms and languages
In other words, some of the best ways to become a better programmer are not new coding techniques per se. Similarly, they're not things you learn in college either. So let's break it down a bit more.
Regarding #1. As an observation, you will likely be working on a team in the future, but for many things you likely are not working on a team now given that you are in high school. Working on a team means a few things: tolerating other people's coding styles, other people's designs and architectures, Bob's bad taco breath on Taco Tuesday's, submitting code to a repository, having a build server, and having other people hate on your beloved code. Things you can do now:
- Learn about a source control system. Use one for your personal projects. I recommend Mercurial or Git. Learn about and use branching; branching is not just some shiny concept it's a real tool in making sure code produced by a team is stable when it reaches production.
- Set up a continuous build server of some sort. This won't take that long. Use this build server with your source control for one or more of your projects.
- Buy gum for Bob.
Regarding #2. Find people better than you to learn from. This may be hard in high school. Look for people that are humble, don't routinely spout specifications, avoid flame wars, and are respected by others. Then read their code and watch how they interact with people around them.
Regarding #3. Learn what unit tests are if you don't know and why people write them (hint, it's not only for correctness of code). Learn a testing framework like NUnit etc. Find out how mocking can fit into (but is not equivalent to) unit testing. Understand what it means to write testable code - this tends to also be more modular and have better architecture too. Even though they are not always appropriate, understand dependency injectors/dependency injection. I write C++ daily without a dependency injector but the concepts are still applied from time to time in my code and it makes it better.
Regarding #4. Learn categorically new ways to program things and approach problems. This will probably make sense do do once you know Java well. It's like learning about programming patterns: learn it after you've done a bunch of programming (>10K lines of code) so you can really feel their worth and recognize patterns you've already done. Similarly, other languages' paradigms can help you in your current language sometimes because you may simulate a portion of a concept to best solve a problem. It also doesn't hurt to study a bit of history here.
Also, as a bonus: learn how to communicate your ideas well. I had much frustration for many years because I was poor at communicating my ideas and they were stuck in my head. This takes practice and perseverance, but frees you from being alone with your ideas.
Most of these things you will not learn in college. You will learn about algorithms, theory, perhaps the software engineering practices flavor of the month. But these things (with the exception of which source control is the current flavor, the concepts remaining similar) will hopefully change less and help you more. That's not to down on the theory, just to supplement it. I've written a couple state machines in the last week or two.