Java noob的缺陷是什么?

时间:2009-05-05 00:27:08

标签: java

我在SO上经历了一些Java问题。我必须说这里的内容是pretty well written,SO上的Java人员可以真正抽出答案。

但我总是找到Java人的Java答案。这本身就很棒,但我是一个Java菜鸟。所以我并不关心"Joint union in type parameter variance"的运作方式。它可能很方便,但现在......它不是。

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

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

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

23 个答案:

答案 0 :(得分:16)

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

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

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

答案 1 :(得分:14)

说通过引用传递对象。

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

Java only works with pass by value.

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

答案 2 :(得分:10)

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

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

  

通过使用标准库,您可以使用   编写它的专家的优势   和那些使用过的人的经验   它在你之前。

     

[...]每个程序员都应该熟悉   内容为java.lang,   java.util,在较小程度上,   java.io

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

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

答案 3 :(得分:10)

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

答案 4 :(得分:10)

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

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

答案 5 :(得分:9)

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

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

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

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

Sun有一个简短的page about autoboxing,旨在吸引更有经验的程序员,但可能会提供信息。

答案 6 :(得分:8)

考虑在代码上运行FindBugsavailable as an Eclipse plugin)。它可以标记许多常见错误。随着检测工具的出现,我认为这对初学者来说是一个很好的选择,因为它不会挑剔无关紧要的细节。

答案 7 :(得分:8)

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

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

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

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


编辑:还有一些事情。

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

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

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

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

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

答案 8 :(得分:7)

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

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

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

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

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

IDE将完全解决Java 平台基本问题。

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

答案 9 :(得分:7)

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

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

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

答案 10 :(得分:5)

总是:

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
    ...
}

答案 11 :(得分:5)

注册JavaBlackBelt并开始在那里进行测试。正如您在浏览首页时所看到的那样,它们涵盖了从最简单的事物到极其先进的主题的任何内容。

不要因为没有通过任何测试而感到羞耻,在继续之前告诉你应该多了解一些内容:)

答案 12 :(得分:5)

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

答案 13 :(得分:5)

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

答案 14 :(得分:5)

静态决赛可以融入课堂。

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中本地运行,它会静默地重新编译所有类,然后在服务器上进行增量更新。嘿,我的改变在哪里?

答案 15 :(得分:4)

我看到一些错误让人们在编程方面经验丰富,而不是Java:

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

答案 16 :(得分:4)

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

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

答案 17 :(得分:3)

我不得不说。

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

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

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

String str = "";
foo (str);

System.out.println(str);

你可以听到“等,WTF!”来自一个菜鸟。

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

答案 18 :(得分:2)

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

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

答案 19 :(得分:2)

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

HashMap myStore = new HashMap();

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

Map myStore = new Hashtable();

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

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

答案 20 :(得分:2)

确保您了解OOP而不是将所有内容都设置为静态。并找出有关堆栈溢出的问题: - )。

答案 21 :(得分:2)

equals()与自动装箱相结合可能会变得非常疯狂:

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

答案 22 :(得分:0)

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

更高级的说明习惯于编码Specs首先紧跟unit testing - 但这不仅仅适用于Java。但是很多人又把这个放进去了。