Java noob的缺陷是什么?

我在SO上经历了一些Java问题。 我必须说这里的内容写得非常好 ,SO上的Java人员可以真正抽出答案。

但我总是发现Java人员的Java答案。 这本身就很棒,但我是一个Java菜鸟。 所以我并不关心“类型参数方差联合联合”的运作方式。 它可能很方便,但现在……它不是。

Java for a noob(来自PHP和Python)什么是cheatcodes?

如果你可以链接到一个SO答案(可能在那里但我找不到)或者写出Java与其他语言不同的东西是什么? (在基础水平上)

有些人可能称之为Java Gotchas(我找不到官方的)

有一系列半官方的“陷阱”,被称为Java Puzzlers,并记录在一本同名的书中 ; 您可能还会在网上找到一些截屏video。 Joshua Bloch和Neal Gafter会定期提出一系列看似无害的挑战,并系统地删除您所了解的任何概念,即使是Java语言中最模糊的基础知识也是如此。

在一个稍微不那么愤世嫉俗的说明中,如果你想避免许多常见的设计和实现,你可以看看前面提到的Joshua Bloch的Effective Java ,它有很多关于如何开始设计几个重要的 – 但经常写得很糟糕 – 用Java编写组件的方面,包括如何正确实现equals()hashCode()的合同的全面解释,以及为什么你应该避免clone()鼠疫。

哦,不要将字符串与==运算符进行比较。

说通过引用传递对象。

实际上,方法只适用于通过值传递的对象引用的副本。

Java仅适用于传递值。

另外值得一读: Is-java-pass-by-reference?

一个小问题:在Google上搜索Java类并期望找到最新信息。 建议:始终包含版本号,即搜索“inputstream 6”而不是“inputstream”。 同样,要注意网上的教程,很多都已经过时了。

我认为另一个常见的初学者陷阱是重新发明轮子 。 也就是说,当库(图书馆已经提供)(可能更好)实现时,自己编写一些(低级)算法,数据结构或实用程序。

有关这一点的详细说明,请阅读Joshua Bloch的Effective Java (第2版)中的第47项: 了解并使用这些库 。 (阅读整本书,在它的同时!;-)我将引用他给出的一些主要建议:

通过使用标准库,您可以利用编写它的专家以及在您之前使用它的人的经验。

[…]每个程序员都应该熟悉java.langjava.utiljava.io在较小程度上)的内容。

具体来说, java.util的Java Collections Framework对任何Java程序员,新手或非新手都非常有用; 正如布洛赫先生所说,它绝对“减少了编程工作,同时提高了性能”。

除了Java平台本身附带的库之外,值得一提的一系列Java库是Apache Commons 。 它涵盖了很多方面,被广泛使用,并且经常在标准库停止的地方继续使用。 此外,虽然我自己还没有使用它们,但Google最近似乎推出了一些补充Java平台的高质量Java库,例如Google Collections ( 有趣的文章 )。 编辑 :既然我已经熟悉了Google Collections,我可以说在学习Java Collections框架后,该库绝对值得研究; 它似乎是完美的延伸! 从我链接到的Javalobby文章开始,并查看主要开发人员Kevin Bourrillion的演示文稿: 第1 部分和第2部分 。

标量类型int和盒装类型Integer之间的区别对于Java新手来说是令人惊讶的。

Java总是区分“标量”类型,它们不是类: boolean (true / false), char (无符号16位), short (带符号16位), int (带符号32位),以及long (签名64位); 以及其他所有类,最终派生自Object类。

当你想使用像List这样的generics集合之类的东西时会出现问题。 List可以包含从Object派生的任何内容,但不包含标量值。 因此,为了将int值存储到List ,需要将它们包装到一个名为Integer的类的实例中,该类派生自Object

在旧版本的Java中,您还需要使用.intValue()方法调用显式地从Integer类中获取值。 在较新版本的Java中,此转换称为“拆箱”,在某些情况下是自动转换。

Sun有一个关于自动装箱的简短页面,它针对的是一个更有经验的程序员,但可能会提供信息。

书签javadocs: http : //java.sun.com/javase/6/docs/api/index.html

更好的是,在本地安装它们并在本地计算机上为页面添加书签,以便更快地查找和离线浏览。

考虑在代码上运行FindBugs ( 作为Eclipse插件提供 )。 它可以标记许多常见错误。 作为检查工具,我认为这对初学者来说是一个很好的选择,因为它不会挑剔无关紧要的细节。

我认为最好的“作弊码”是“不要聪明,写下愚蠢的代码”。

这些术语有点加载,但基本上你想要在编写它们时简单易懂,因为当你稍后再回到它时它们会很容易阅读。 现在,JVM比你更聪明,而非哑代码通常会尝试“更有效”地执行某些操作,这可能会阻止JVM做更聪明的事情。

看看http://java.sun.com/developer/technicalArticles/Interviews/devinsight_1/

请注意:编写智能代码是可以的,您只需先certificate是必要的:)


编辑:还有一些事情。

  • 写了很多代码。 实践是完美的 – 始终努力以最好的方式做到这一点。 如果您稍后再回到代码中,您可能已经学会了一两件事,因为这样可以让您了解早先的选择,从而让您在下次做出选择时做出更好的决策。 这包括文件 ! 文档是允许其他人使用您的代码而不详细了解它的原因。

  • 阅读了很多代码。 设置IDE,以便您可以查看尽可能多的源代码。 通过在Eclipse中使用JDK作为JVM,源代码会自动附加,因此您可以查看在断点处遇到的任何内容的源代码。 在代码中包含来自例如Apache的jar时,请包含源代码,以便您可以看到它的作用。 有一天它会帮助你弄清楚为什么会发生某种事情以及如何避免它。

  • 与同行合作。 其他类似程度的程序员可能会为情境提供输入 – 甚至可能只是听他们的解释澄清了你的想法 – 你也可以帮助他们。 通过合作和共同评估,您可以相互利用。

  • Sun的Java Tutorial涵盖了很多Java库,并且学习那些涵盖运行时基本部分(java.lang,java.io)的内容并阅读其余内容(只是为了知道存在的内容)将使您成为更熟练的程序员。 您将知道工具箱中的内容!

  • 参与Stack Overflow。 为问题写出好的答案(即使他们已经得到了回答,却很糟糕),这样你就可以将自己的经验用到文字中,这就是编写文档的做法:)

这可能有点过于基本的建议,所以请原谅我,如果我冒犯你提出它,但我已经看到太多的Java代码开始自由抛出static关键字,似乎不考虑它是什么。 因此,如果你看到一个警告抱怨“静态引用非静态值”或某些这样的事情,不要试图通过随机地将static放在一个非静态的东西来解决它,除非这样做是有道理的。

这是一个小问题,在你知道它的术语之前你可能无法搜索:“package-private”。 在Java中,存在于C ++等其他地方的公共,受保护和私有范围。 如果您还不知道,可以阅读它们的用途。 但请注意,如果您没有指定某些内容是公共的,受保护的还是私有的,那么这些都不是。 它是包私有的,除了缺少关键字之外没有指定它的关键字。 包私有的东西作为私有值充当另一个包中的任何东西,公共到同一个包中的东西。

另一个随机提示:使用包。 可以不使用package com.whatever.foo;开始你的.java文件package com.whatever.foo; 如果你正在使用命令行javac,你会发现在你的工作目录中显示缺少该行的文件很好,但它几乎总会在以后变得很痛苦。 并且无论如何都停止使用命令行javac。 使用Eclipse。

如果您已熟悉命令式C语言,那么Java是一种非常直接的语言。 深层问题与语言无关,但更广泛地与静态(和强烈)类型,单inheritance,OO语言相关。

我也谦卑地不同意我的Java兄弟,并建议您使用文本编辑器和命令行学习基础知识。 这就是JVM的具体问题最为突出。

记住Java和其他语言之间最重要的区别:Java既是语言又是平台。

你需要理解类路径的概念; 逻辑包结构与文件系统中的(类似)实施例之间的关系。

在命令行输入时,输入’java’,’javac’等会怎样? 学习基础知识。

IDE将完全克服Java 平台的这些基本问题。

如果您愿意,我还建议您阅读Java语言规范和(是)JVM规范。 如果Mastery是你所追求的,那么当你开始用Java旅行时,请确保你找到了类加载器和相关问题。

使用Eclipse进行Java编辑/开发/调试。 或者其他一些IDE可能,但为了上帝的缘故,不要使用记事本和命令行。

总是:

 String a = "wow, not the same"; String b = "wow, not the same"; String c = new String("wow, not the same"); if (a == b) { //happens to evaluate to true, but you shouldn't do this ... } if (a == c) { //evaluates to false, which is why you shouldn't do it ... } //This is how you *should* do this if (a.equals(b)) { //evaluates to true ... } if (a.equals(c)) { //evaluates to true ... } 

注册JavaBlackBelt并开始在那里进行测试。 正如您可以通过浏览首页快速看到的那样,它们涵盖了从最简单的事物到令人难以置信的高级主题的任何内容。

并且不要为任何测试失败感到羞耻,失败只是在继续之前告诉你应该学到更多什么:)

迷恋设计模式! 我不会过分担心设计模式。 如果你意识到它们的存在是很好的,那么你就会知道你团队的其他成员在谈论什么,但现在重要的只是探索核心Java API。 当你对它们感到满意时,我真的会努力学习如何编写干净且自我记录的代码。 当你回去并需要记住你在做什么时,这将为你节省大量的时间和精力。

静态决赛可以融入课堂。

 public class Foo { public static final String A_STRING="A_STRING"; } public class Bar { public void printString() { System.out.println(Foo.A_STRING);} } 

现在编译两者,然后更改“Foo”并重新编译Foo但重新编译Bar。 Bar仍然会打印出A_STRING的旧值。 要亲自体验一下,在eclipse中本地运行,它会静默地重新编译所有类,然后在服务器上进行增量更新。 嘿,我的改变在哪里?

Java与其他语言的不同之处是什么? (在基础水平上)

在基本层面上,它与其他OOP语言没有什么不同。 然而,与简单的程序编程相比,它是一个全新的世界……或者是一个进化过的世界。

我见过的一些错误让人们在编程方面经验丰富而在Java方面没有经验:

  1. 类隐式扩展Object
  2. 类隐式导入java.lang.*
  3. instanceof不需要非空检查
  4. 向上转换,例如((Object)new Integer(1)).toString() ,几乎从不有用,因为它不影响动态方法选择
  5. 字符串是不可变的。 无需复制或克隆它们。
  6. 不要依赖垃圾收集器或finalize()来执行资源(而不是内存)管理。 应明确关闭资源,例如文件。
  7. 一旦显示,Swing组件只能从AWT事件线程访问(通常使用SwingUtilities.invokeLater() )。
  8. 通常,当多个线程共享相同的可变/有状态对象时,要非常非常小心。 首先复制对象,或者准备使用一些synchronized块, wait()notify()

我不得不说。

最常见的noob陷阱短语之一,如“方法上的参数总是作为参考传递,因为对象变量是引用,对吧?”

所以当你看到类似的东西时:

 public void foo(String str){ str="yeah, this should work!"; } String str = ""; foo (str); System.out.println(str); 

你可以听到“等待,跆拳道!” 来自一个菜鸟。

根据我的经验,java noobs不了解StringBuffer / StringBuilder。 对于不可变的对象都没有。

另一个陷阱:确定调试器是一个调试器,并使用Eclipse调试器而不花时间学习它。

既然你说你正在使用Eclipse,那么这里有一系列关于调试器的7个优秀video教程。 我强烈建议花时间(7 * 15分钟)观看它们。

避免比你需要更具体。 您可能想将存储对象视为HashMap:

 HashMap myStore = new HashMap(); 

但我建议只考虑它作为Map(界面):

 Map myStore = new Hashtable(); 

你的其余代码不需要知道我们如何实现myStore,它只需要知道myStore是某种Map。 这样我们可以稍后更改实现类型(HashMap,Hashtable,…),只会影响一行代码。

我选择Hashtable作为示例,而不是HashMap,因为Hashtable是线程安全的。 在multithreading应用程序中,这避免了两个线程同时读取和更改同一HashMap可以开始抛出exception的问题。

确保你理解OOP而不是让一切都是静态的。 并找出有关堆栈溢出的问题:-)。

equals()与autoboxing结合起来会变得非常疯狂:

 Integer X = 9000; Integer Z = 9000; short y = 9000; boolean b1 = (X == Z); boolean b2 = (X == y); boolean b3 = (X.equals(Z)); boolean b4 = (X.equals(y)); System.out.println(b1 + " " + b2 + " " + b3 + " " + b4); 

输出:

 false true true false 

根据我的经验, hashCode Java的人永远不会覆盖equalshashCodetoString方法,无论对象的目的是什么。 也没有人会为设置简单的日志记录系统而烦恼。 当我看到System.out.println我觉得我已准备好打破手指! 但是很多经验丰富的程序员也正在努力完成任务。

更高级的注意事项是习惯于编码,其中Specs首先紧跟unit testing – 但这不仅仅适用于Java。 但是很多人都把这个放进去了。