帮助我了解自Java 1.4.2以来错过的一切


14

我即将开始我的职业生涯,最初是软件开发人员,我很可能会写很多Java代码。我对我将要写的具体内容并不了解,此外,无论如何我对代码都有广泛的兴趣。

由于不值得讨论的原因,我的上一次实习是让我只为Java 1.3和1.4 SDK进行编码。另外,我的大学教育主要集中在算法,数据结构和其他理论上,而不是语言功能或库上。

因此,考虑到以上几点,当前版本的Java(无论现在我们要增加多少?)中的哪些功能,类等,值得我花时间阅读,为什么?自1.4.2起我错过了什么,这使您作为程序员的生活更加轻松?

有关如何发现某个特定软件包或将其投入使用的示例和故事也很棒。


4
这些不值得讨论的原因是什么?我们很多人都很感兴趣...
5arx 2010年

@ 5arx好吧,我使用1.4版的Java进行了机器人编程,因为出于某种原因,这正是我们平台所支持的。
Daniel Gratzer

Answers:


15

我认为最重要的更改是:

  • 泛型(例如,类型化的集合,如Set)

  • 增强的for循环(用于(String s:set){...})

  • 自动装箱/拆箱(自动在Integer等类型之间转换为int,反之亦然)

  • Typesafe枚举(枚举现在是关键字,可以从枚举中创建类型)

  • Varargs(对于printf()函数,允许可变数量的参数)

  • 静态导入(现在可以导入类的静态方法,例如java.lang.Math)

  • 注解

  • java.util.concurrent(演示Java的并发性)

另请参阅您的目标是Java?,以更好地了解这三个版本。


1
++增强的for循环,自动装箱/拆箱,varargs,静态导入很简单
Michael Wiles 2010年

Java程序员为什么将for-each循环称为“增强for循环”?
Maxpm 2012年

2
@Maxpm因为这就是Java语言规范中的调用方式。根据JLS,有一些基本的for循环和增强的for循环。我不确定为什么他们决定那样做。可能是因为语法没有使用特殊的关键字,并且不与常规循环混合使用。
马尔科姆

10

日常编程生活中最重要的变化就是引入了泛型,这种泛型很可能会在要求您编写的每个新模块中使用,这是一个令人困惑的新语法。

泛型是一种机制,例如允许a List包含字符串而不是裸对象,其中编译器强制将要放入列表中的项目为String,并且它知道从列表中获得项目时为String。 。

这可以使程序更好,因为避免了将显式运行时强制转换为目标类型(如果弄错了,这通常是错误的来源),并且IDE可以帮助您完成所有肮脏的工作,因为它比您对代码的了解要多得多。它只是对象列表时就这样做了。

Joshua Bloch为Generics撰写了很好的介绍,可以在http://java.sun.com/docs/books/effective/作为示例章节获得。


请不要告诉Groovy的人!“这避免了将运行时强制转换为目标类型,从而使程序更好。” def whatever....
Dan Rosenstark

@Yar,进行了更明确的编辑。我喜欢 “ def”或“ var”属性。让我的生活更轻松一点。

是的,我最近才用Objective-C来思考这个问题,而idwhich defvar....但是,同样地,100%静态类型的安全性确实很棒。
丹·罗森斯塔克

@Yar:您会爱上Ada :)
mattnz'2

@mattnz为什么特别?当我们在这里时,它是否可以在JVM上运行?
丹·罗森斯塔克2012年

6

自动装箱是Java 5引入的一项不错的功能。就像在C#中一样,编译器现在可以在原始(基本)类型及其对应的对象包装类(从int到Integer等)之间进行自动转换,然后再返回。这使得使用Java Collections的工作减少了很多。

我认为,for-each循环在Java 5中也是新功能。它使遍历数组(和集合)变得更加容易,因为它消除了涉及索引变量或迭代器的设置和管理的通常的混乱情况。例如:

void myMethod(Collection<myObjectType> c) {
    for (myObjectType o : c)
        o.foo();
}

6

枚举,以替换最终的静态变量和常量,并帮助您删除对字符串和魔术数字的引用。取自sun / oracle的好人的一个例子:

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7),
    PLUTO   (1.27e+22,  1.137e6);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    public double mass()   { return mass; }
    public double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    public double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

public static void main(String[] args) {
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }

6

java.util.concurrent在1.5 引入。最好的学习资源是(可能)《Java Concurrency in Practice》一书。与其他任何事物相比,IMHO并发性是Java最重要的竞争优势,因此绝对值得了解。


1
+1对于提及并发包。可悲的是,如此多的开发人员仍然使用诸如Threads,wait()/ notify()和并发等并发原语...
Oliver Weiler 2010年

确实。java.util.concurrent并发原语就像自动内存管理到手动内存管理一样。使用后者只是花费更多时间进行调试的秘诀,没有任何优势。
Joonas Pulakka 2010年

执行者来救援!在Java 6中甚至更好

如果可以的话,+ 1000-这本书太神奇了
Gary Rowe 2010年

4

好吧,StringBuilder帮助我加快了程序的速度。这等效于无线程StringBuffer安全。


是的 有效的Java声明StringBuffer已过时,应由StringBuilder代替。
加里·罗

1
+源级别为1.5或更高版本的字符串串联可自动使用StringBuilder代替StringBuffer。

4

我将对@ykombinator的有用答案进行分类,以提供帮助。他的清单是您在进行“常规” java开发时每天将使用的元素的清单。

低影响和低难度:

  • 增强的for循环(用于(String s:set){...})
  • 自动装箱/拆箱(自动在Integer等类型之间转换为int,反之亦然)
  • Varargs(对于printf()函数,允许可变数量的参数)
  • 静态导入(现在可以导入类的静态方法,例如java.lang.Math)

高影响力和中等难度:

  • Typesafe枚举(枚举现在是关键字,可以从枚举中创建类型)

高影响力和高难度:

  • 注解
  • 泛型

低影响和高难度(除非您进行高级线程化,否则只会使用)

  • java.util.concurrent(演示Java的并发性)

因此,我建议您通读有关低影响力低难度零件的文档/帮助-它们很容易拿起。将时间花在注解和泛型上-注解非常有用,泛型会变得相当复杂。

仅在需要执行线程处理时才查看新的并发内容。


4

由于我不到50岁,因此无法发表评论,我将留下答案。已经提到过了,但我会再重复一遍:注释! 这种元数据成为我多年Java经验中最重要的事情。它像某些框架一样很好地使用,它使代码更加简洁明了。例如,注释可以:

  • 将对象转换为实体@Entity
  • 将方法转换为REST服务@GET
  • 说明方法永远不会返回null @nonnull
  • 将对象设置为用于依赖项注入的字段@inject

当然,您可以构建自己的注释,并知道是否使用反射对方法,类或字段进行注释。


2
确切地说,注释不能这些事情,因为它们只是将元信息放入代码中,而其他代码(通常是特殊的类加载器)可以对代码进行操作。我认为注释是解决许多问题的很好的通用解决方案。

3

以身作则对我有用

这是惯用的Java 6的简单示例

public class Main {
  public static void main(String[] args) {
    // Shows a list forced to be Strings only
    // The Arrays helper uses generics to identify the return type
    // and takes varargs (...) to allow arbitary number of arguments
    List<String> genericisedList = Arrays.asList("A","B","C");

    // Demonstrates a for:each loop (read as for each item in genericisedList)
    for (String item: genericisedList) {
      System.out.printf("Using print formatting: %s%n",item);
    }

    // Note that the object is initialised directly with a primitive (autoboxing)
    Integer autoboxedInteger = 1;
    System.out.println(autoboxedInteger);

  }
}

不用理会Java5,它相对于Java6已经过时了。

下一步,注释。这些只是定义了代码的各个方面,允许注释阅读器为您填写样板配置。考虑一个使用JAX-RS规范的简单Web服务(它了解RESTful URI)。您不想打扰所有令人讨厌的WSDL并与Axis2等混为一谈,您想要一个快速的结果。对,这样做:

// Response to URIs that start with /Service (after the application context name)
@Path("/Service")
public class WebService {

  // Respond to GET requests within the /Service selection
  @GET
  // Specify a path matcher that takes anything and assigns it to rawPathParams
  @Path("/{rawPathParams:.*}")
  public Response service(@Context HttpServletRequest request, @PathParam("rawPathParams") String rawPathParams) {
    // Do some stuff with the raw path parameters 

    // Return a 200_OK
    return Response.status(200).build();
  }
}

砰。在web.xml中散布一些配置魔术,您就可以使用了。如果您使用Maven进行构建并配置了Jetty插件,则您的项目将立即具有它自己的小型Web服务器(无需为JBoss或Tomcat摆弄),并且上面的代码将响应形成:

GET http://localhost:8080/contextName/Service/the/raw/path/params

任务完成。


3

哇,这是过去的爆炸!我已经有4年没有使用Java了,那时一切都没有改变!

有一个按功能列出的功能列表,但这是重要的一点(当然是pla窃的)...

J2SE 5.0(2004年9月30日)

  • 泛型:为集合提供编译时(静态)类型安全性,并且无需进行大多数类型转换(类型转换)。
  • 元数据:也称为注释;允许使用其他数据来标记诸如类和方法之类的语言构造,然后可以由支持元数据的实用程序对其进行处理。
  • 自动装箱/拆箱:在原始类型(例如int)和原始包装器类(例如Integer)之间自动转换。
  • 枚举:enum关键字创建一个类型安全的,有序的值列表(例如Day.MONDAY,Day.TUESDAY等)。以前,这只能通过非类型安全的常量整数或手动构造的类(类型安全的枚举模式)来实现。
  • 摇摆:新的外观和感觉,称为合成器。
  • Varargs:现在可以使用类型名称和三个点(例如void drawtext(String ... lines))声明方法的最后一个参数。在调用代码中,可以使用任意数量的该类型的参数,然后将它们放置在数组中以传递给方法,或者,调用代码可以传递该类型的数组。
  • 每个循环的增强功能:for循环语法得到了扩展,具有特殊语法,可使用以下形式的构造对数组或任何Iterable(例如标准Collection类)的每个成员进行迭代:

Java SE 6(2006年12月11日)

  • 不再支持较旧的Win9x版本。非官方地,Java 6 Update 7是Java的最新版本,可以在这些Windows版本上使用。据信这是由于Update 10中的重大更改所致。
  • 脚本语言支持:通用API,用于与脚本语言紧密集成,并内置Mozilla JavaScript Rhino集成
  • 核心平台和Swing的性能大幅提升。
  • 通过JAX-WS改进的Web服务支持
  • JDBC 4.0支持。
  • Java Compiler API一种API,允许Java程序以编程方式选择和调用Java Compiler。
  • 将JAXB升级到2.0版:包括StAX解析器的集成。
  • 支持可插入注释
  • GUI的许多改进,例如将SwingWorker与API集成,表排序和过滤以及真正的Swing双缓冲(消除了灰区效应)。
  • JVM的改进包括:同步和编译器性能优化,新算法和对现有垃圾回收算法的升级以及应用程序启动性能。

就是这样 Java SE 7.0看起来更有趣,但尚未发布。

考虑到过去4年中C#中添加了多少种新的语言功能和API,我感到非常惊讶。Sun / Oracle发生了什么事?


Sun决定开源Java。这是确保无论Oracle决定做什么事情,我们仍然可以在Linux机器上运行OpenJDK。那只会延迟他们18-24个月...

@Thorbjørn-可能可以解释这一点。可惜这次收购造成了多少破坏。我想C#具有相对的稳定性:自2006年以来,我们就开始使用lambda-从现在看来,直到2012年,他们才开始使用Java。
sheikhjabootie 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.