ช่วยฉันติดตามสิ่งที่ฉันพลาดไปตั้งแต่ Java 1.4.2 [ปิด]


14

ฉันกำลังจะเริ่มต้นอาชีพอาชีพครั้งแรกในฐานะนักพัฒนาซอฟต์แวร์และฉันมีแนวโน้มที่จะเขียนโค้ด Java จำนวนมาก ฉันไม่รู้มากเกี่ยวกับสิ่งที่ฉันจะเขียนเฉพาะและนอกจากนี้ฉันมีความสนใจในวงกว้างเมื่อพูดถึงโค้ด

ด้วยเหตุผลที่ไม่ควรพูดถึงการฝึกงานครั้งสุดท้ายของฉันทำให้ฉันเข้ารหัสเฉพาะ Java 1.3 และ 1.4 SDK เท่านั้น นอกจากนี้การศึกษาในมหาวิทยาลัยของฉันยังเน้นเรื่องอัลกอริธึมโครงสร้างข้อมูลและทฤษฎีอื่น ๆ ไม่ใช่คุณสมบัติทางภาษาหรือห้องสมุด

ดังนั้นด้วยความในใจข้างต้นคุณสมบัติอะไร, คลาส, และอื่น ๆ ใน Java เวอร์ชันปัจจุบัน (ตอนนี้เรากำลังใช้เลขอะไรอยู่) จะคุ้มค่ากับเวลาที่ฉันอ่านและทำไม? ฉันพลาดอะไรไปตั้งแต่ 1.4.2 ที่ทำให้ชีวิตของคุณในฐานะโปรแกรมเมอร์ง่ายขึ้น?

ตัวอย่างและเรื่องราวของวิธีที่คุณค้นพบแพคเกจเฉพาะหรือบางอย่างและนำไปใช้จะดีมาก


4
อะไรคือเหตุผลเหล่านี้ที่ไม่ควรพูดถึง พวกเราหลายคนสนใจ ...
5arx

@ 5arx ฉันทำงานกับจาวาเวอร์ชัน 1.4 สำหรับการเขียนโปรแกรมหุ่นยนต์ด้วยเหตุผลบางประการนั่นคือสิ่งที่แพลตฟอร์มของเรารองรับ
Daniel Gratzer

คำตอบ:


15

การเปลี่ยนแปลงที่ฉันพิจารณาว่าสำคัญที่สุดคือ:

  • ยาสามัญ (เช่นคอลเลกชันที่พิมพ์เช่นชุด)

  • ปรับปรุงสำหรับลูป (สำหรับ (String s: set) {... })

  • Autoboxing / unboxing (แปลงโดยอัตโนมัติระหว่างประเภทเช่นจำนวนเต็มเป็น int และในทางกลับกัน)

  • Typesafe enums (enum เป็นคำหลักประเภทสามารถสร้างได้จาก enums)

  • Varargs (สำหรับฟังก์ชัน printf () อนุญาตจำนวนอาร์กิวเมนต์ได้)

  • การนำเข้าแบบสแตติก (ขณะนี้สามารถนำเข้าวิธีการคงที่ของคลาสเช่น java.lang.Math)

  • คำอธิบายประกอบ

  • java.util.concurrent (แสดงให้เห็นถึงการทำงานพร้อมกันของ java)

ยังอ่านJava ที่คุณตั้งเป้าไว้คืออะไร? เพื่อทำความเข้าใจให้ดีขึ้นสำหรับแต่ละรุ่นทั้งสาม


1
++ การปรับปรุงสำหรับลูป, autoboxing / unboxing, varargs, การนำเข้าแบบสแตติกง่าย
Michael Wiles

เหตุใดโปรแกรมเมอร์ของจาวาจึงเรียกแต่ละลูป " forลูปที่ปรับปรุงแล้ว"
Maxpm

2
@ Maxax เนื่องจากว่าเป็นวิธีที่เรียกใน Java Language Specification ตาม JLS มีพื้นฐานสำหรับลูปและปรับปรุงสำหรับลูป ฉันไม่แน่ใจว่าทำไมพวกเขาตัดสินใจทำเช่นนั้น อาจเป็นเพราะไวยากรณ์ไม่ได้ใช้คำหลักพิเศษและการเรียงลำดับของการผสมกับลูปปกติ
Malcolm

10

การเปลี่ยนแปลงที่สำคัญที่สุดเพียงอย่างเดียวในชีวิตประจำวันของคุณในการเขียนโปรแกรมคือการแนะนำgenericsซึ่งมักจะใช้ในโมดูลใหม่ทุกครั้งที่คุณจะถูกขอให้เขียนและเป็นไวยากรณ์ใหม่ที่ทำให้เกิดความสับสน

Generics เป็นกลไกที่อนุญาตให้เช่น a Listเพื่อบรรจุสตริงแทนที่จะเป็นวัตถุเปล่าโดยที่คอมไพเลอร์บังคับให้ไอเท็มที่จะใส่เข้าไปในรายการนั้นคือสตริงและรู้ว่าเมื่อคุณเอาไอเท็มออกจากรายการมันจะเป็นสตริง .

สิ่งนี้ทำให้โปรแกรมที่ดีกว่าในขณะที่คุณหลีกเลี่ยงการใช้งาน runtime ที่ชัดเจนกับประเภทเป้าหมาย (ซึ่งเป็นแหล่งที่มาของข้อผิดพลาดบ่อยครั้งถ้าคุณทำผิด) และ IDE สามารถช่วยคุณทำงานสกปรกทั้งหมดได้เพราะรู้รหัสของคุณมากกว่า มันทำเมื่อมันเป็นเพียงรายการของวัตถุ

Joshua Bloch ได้เขียนแนะนำเบื้องต้นเกี่ยวกับ Generics ซึ่งมีอยู่ในบทตัวอย่างที่http://java.sun.com/docs/books/effective/


กรุณาอย่าบอกคน Groovy! "สิ่งนี้ทำให้โปรแกรมที่ดีกว่าในขณะที่คุณหลีกเลี่ยงการใช้งาน runtime ไปยังประเภทเป้าหมาย" def whatever....
Dan Rosenstark

@ ใช่แก้ไขให้ชัดเจนยิ่งขึ้น ฉันจะรักแอตทริบิวต์ "def" หรือ "var" จะทำให้ชีวิตของฉันง่ายขึ้นเล็กน้อย

ใช่ฉันเพิ่งคิดเมื่อเร็ว ๆ นี้กับ Objective-C และidนั่นคือdefหรือvar.... แต่แล้วอีกครั้งความปลอดภัยของการพิมพ์สแตติก 100% นั้นน่าทึ่งจริงๆ
Dan Rosenstark

@Yar: คุณจะรัก Ada :)
mattnz

@mattnz ทำไมโดยเฉพาะ? และในขณะที่เราอยู่ที่นี่มันทำงานบน JVM หรือไม่?
Dan Rosenstark

6

Autoboxingเป็นคุณสมบัติที่ดีที่นำมาใช้กับ Java 5 เช่นเดียวกับใน C # ตอนนี้คอมไพเลอร์ทำให้การแปลงอัตโนมัติระหว่างชนิดดั้งเดิม (พื้นฐาน) และคลาส wrapper วัตถุที่สอดคล้องกัน (int ถึง Integer ฯลฯ ) และกลับมาอีกครั้ง นั่นทำให้การทำงานกับ Java Collections เจ็บปวดน้อยลง

สำหรับการวนซ้ำแต่ละครั้งนั้นใหม่ใน Java 5 เช่นกันฉันคิดว่า มันทำให้การวนซ้ำของอาร์เรย์ (และคอลเลกชัน) ง่ายขึ้นเพราะจะขจัดความยุ่งเหยิงตามปกติที่เกี่ยวข้องกับการตั้งค่าและการจัดการตัวแปรดัชนีหรือตัววนซ้ำมาก ตัวอย่าง:

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

6

Enumsเพื่อแทนที่สถิตยศาสตร์สุดท้ายและค่าคงที่และช่วยให้คุณลบการอ้างอิงถึงสตริงและหมายเลขมายากล ตัวอย่างที่นำมาจากคนดีที่ดวงอาทิตย์ / พยากรณ์ :

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 สำหรับการกล่าวถึงแพคเกจที่เกิดขึ้นพร้อมกันมันเป็นเรื่องน่าเศร้าที่นักพัฒนาจำนวนมากยังคงใช้การทำงานพร้อมกันอย่างเช่นเธรดรอ () / แจ้ง () และซิงโครไนซ์ ...
Oliver Weiler

จริง java.util.concurrentการทำงานพร้อมกันแบบดั้งเดิมนั้นเหมือนกับการจัดการหน่วยความจำอัตโนมัติไปยังการจัดการหน่วยความจำด้วยตนเอง การใช้งานหลังเป็นเพียงสูตรในการใช้เวลาในการดีบักและไม่มีข้อได้เปรียบ
Joonas Pulakka

ผู้บริหารเพื่อช่วยเหลือ! ดียิ่งขึ้นใน Java 6

+1000 ถ้าทำได้ - หนังสือเล่มนี้น่าทึ่ง
Gary Rowe

4

ดี, StringBuilderช่วยให้ฉันเพื่อเพิ่มความเร็วในโปรแกรมของฉัน มันเทียบเท่ากับStringBufferความปลอดภัยโดยไม่ต้องด้าย


อ๋อ Java ที่มีประสิทธิภาพระบุว่า StringBuffer ล้าสมัยและควรถูกแทนที่ด้วย StringBuilder
Gary Rowe

1
การต่อข้อมูลกับ+สตริงจะใช้ StringBuilder แทน StringBuffer โดยอัตโนมัติสำหรับแหล่งระดับ 1.5 และสูงกว่า

4

ฉันจะช่วยด้วยการจัดหมวดหมู่คำตอบที่เป็นประโยชน์จาก @ykombinator รายการของเขาคือรายการองค์ประกอบที่คุณจะใช้ในชีวิตประจำวันในขณะที่ทำการพัฒนาจาวา "ทั่วไป"

ผลกระทบต่ำและความยากลำบากต่ำ:

  • ปรับปรุงสำหรับลูป (สำหรับ (String s: set) {... })
  • Autoboxing / unboxing (แปลงโดยอัตโนมัติระหว่างประเภทเช่นจำนวนเต็มเป็น int และในทางกลับกัน)
  • Varargs (สำหรับฟังก์ชัน printf () อนุญาตจำนวนอาร์กิวเมนต์ได้)
  • การนำเข้าแบบสแตติก (ขณะนี้สามารถนำเข้าวิธีการคงที่ของคลาสเช่น java.lang.Math)

แรงกระแทกสูงและความยากปานกลาง:

  • Typesafe enums (enum เป็นคำหลักประเภทสามารถสร้างได้จาก enums)

ผลกระทบสูงและความยากลำบากสูง:

  • คำอธิบายประกอบ
  • generics

ผลกระทบต่ำและยากสูง (จะใช้เว้นแต่คุณจะทำเกลียวขั้นสูงเท่านั้น)

  • java.util.concurrent (แสดงให้เห็นถึงการทำงานพร้อมกันของ java)

ฉันขอแนะนำให้คุณอ่านเอกสาร / ความช่วยเหลือเกี่ยวกับชิ้นงานที่มีผลกระทบต่ำและมีผลกระทบต่ำ - พวกมันง่ายต่อการหยิบ ใช้เวลากับคำอธิบายประกอบและ Generics - คำอธิบายประกอบมีความสำคัญมากมีประโยชน์และข้อมูลทั่วไปอาจซับซ้อนกว่านี้

ดูเนื้อหาที่เกิดขึ้นพร้อมกันใหม่เฉพาะในกรณีที่คุณต้องการทำเธรด


4

เนื่องจากฉันไม่สามารถแสดงความคิดเห็นเพราะฉันต่ำกว่า 50 ฉันจะออกคำตอบ มันถูกกล่าวถึงแล้ว แต่ฉันจะทำซ้ำอีกครั้ง: คำอธิบายประกอบ! ข้อมูลเมตาชนิดนี้กลายเป็นสิ่งที่สำคัญที่สุดในประสบการณ์ชวาของฉัน มันใช้งานได้ดีเหมือนเฟรมเวิร์กบางตัวทำให้โค้ดกระชับและสะอาดยิ่งขึ้น ตัวอย่างเช่นคำอธิบายประกอบสามารถ:

  • แปลงวัตถุเป็นเอนทิตี@Entity
  • แปลงวิธีเป็นบริการ REST @GET
  • อธิบายว่าวิธีการหนึ่งจะไม่ส่งคืน null @nonnull
  • ตั้งค่าวัตถุเป็นเขตข้อมูลสำหรับการฉีดพึ่งพา@inject

และแน่นอนว่าคุณสามารถสร้างคำอธิบายประกอบของคุณเองและรู้ว่าวิธีการเรียนหรือฟิลด์จะมีคำอธิบายประกอบโดยใช้การสะท้อน


2
เพื่อให้คำอธิบายประกอบที่แม่นยำไม่สามารถทำสิ่งเหล่านี้ได้เนื่องจากพวกเขาเพิ่งวางเมตาดาต้าลงในโค้ดซึ่งโค้ดอื่น ๆ ซึ่งบ่อยครั้งที่ classloader พิเศษสามารถดำเนินการต่อได้ ฉันคิดว่าคำอธิบายประกอบจะเป็นวิธีแก้ปัญหาทั่วไปที่ดีมากสำหรับปัญหามากมาย

3

การเรียนรู้จากตัวอย่างใช้ได้ผลสำหรับฉัน

นี่คือตัวอย่างย่อของ idiomatic 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 (ทำความเข้าใจกับ RESTful URIs) คุณไม่ต้องการยุ่งกับการทำ 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 โครงการของคุณจะมีเว็บเซิร์ฟเวอร์ตัวเล็ก ๆ ของตัวเองทันทีที่ออกจากกล่อง แบบฟอร์ม:

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

งานเสร็จแล้ว


3

ว้าวนั่นเป็นระเบิดจากอดีต! ฉันไม่ได้ใช้ Java เป็นเวลา 4 ปีแล้วและตอนนี้ก็ไม่มีอะไรเปลี่ยนแปลงเลย!

มีรายการคุณสมบัติตามรุ่นแต่นี่เป็นบิตที่สำคัญ (คัดลอกแน่นอน) ...

J2SE 5.0 (30 กันยายน 2547)

  • Generics: ให้ความปลอดภัยในการรวบรวม (คงที่) สำหรับการรวบรวมและกำจัดความต้องการ typecasts ส่วนใหญ่ (การแปลงประเภท)
  • เมทาดาทา: เรียกอีกอย่างว่าคำอธิบายประกอบ อนุญาตให้สร้างภาษาเช่นชั้นเรียนและวิธีการที่จะติดแท็กด้วยข้อมูลเพิ่มเติมซึ่งสามารถประมวลผลแล้วโดยยูทิลิตี้เมตาดาต้าตระหนัก
  • Autoboxing / unboxing: การแปลงอัตโนมัติระหว่างประเภทดั้งเดิม (เช่น int) และคลาส wrapper ดั้งเดิม (เช่นจำนวนเต็ม)
  • การแจกแจง: คำหลัก enum จะสร้างประเภทค่าที่ปลอดภัยเรียงลำดับรายการ (เช่น Day.MONDAY, Day.TUESDAY เป็นต้น) ก่อนหน้านี้สิ่งนี้สามารถทำได้โดยจำนวนเต็มคงที่ที่ไม่มีความปลอดภัยหรือสร้างคลาสเอง (รูปแบบ typesafe enum)
  • สวิง: รูปลักษณ์และความรู้สึกแบบใหม่ที่เรียกว่า synth
  • Varargs: ขณะนี้พารามิเตอร์สุดท้ายของวิธีสามารถประกาศโดยใช้ชื่อประเภทตามด้วยสามจุด (เช่นโมฆะ drawtext (สาย ... สตริง)) ในรหัสการโทรหมายเลขใด ๆ ของพารามิเตอร์ประเภทนั้นสามารถใช้ได้และพวกเขาจะถูกวางไว้ในอาร์เรย์ที่จะส่งผ่านไปยังวิธีการหรือมิฉะนั้นรหัสการโทรสามารถผ่านอาร์เรย์ประเภทนั้น
  • ปรับปรุงสำหรับแต่ละลูป: ไวยากรณ์สำหรับลูปจะถูกขยายด้วยไวยากรณ์พิเศษสำหรับการวนซ้ำในแต่ละสมาชิกของอาร์เรย์หรือ Iterable ใด ๆ เช่นคลาสคอลเลกชันมาตรฐานโดยใช้โครงสร้างของแบบฟอร์ม:

Java SE 6 (11 ธันวาคม 2549)

  • การสนับสนุนสำหรับ Win9x เวอร์ชั่นเก่าตก Java 6 Update 7 อย่างไม่เป็นทางการคือ Java รุ่นล่าสุดที่แสดงให้ทำงานบน Windows เวอร์ชันเหล่านี้ เชื่อว่าเป็นเพราะการเปลี่ยนแปลงครั้งสำคัญในอัพเดท 10
  • การสนับสนุนภาษาสคริปต์: Generic API สำหรับการรวมอย่างแน่นหนากับภาษาสคริปต์และการรวม Mozilla JavaScript Rhino ในตัว
  • การปรับปรุงประสิทธิภาพที่น่าทึ่งสำหรับแพลตฟอร์มหลักและ Swing
  • ปรับปรุงการสนับสนุนเว็บเซอร์วิสผ่าน JAX-WS
  • สนับสนุน JDBC 4.0
  • Java Compiler API เป็น API ที่อนุญาตให้โปรแกรม Java เพื่อเลือกและเรียกใช้ Java Compiler โดยทางโปรแกรม
  • อัพเกรด JAXB เป็นเวอร์ชั่น 2.0: รวมการรวมตัวแยกวิเคราะห์ StAX
  • รองรับคำอธิบายประกอบแบบเสียบได้
  • การปรับปรุง GUI หลายอย่างเช่นการรวมกันของ SwingWorker ใน API การเรียงลำดับตารางและการกรองและการสวิงคู่ที่แท้จริงของบัฟเฟอร์ (กำจัดเอฟเฟกต์พื้นที่สีเทา)
  • การปรับปรุง JVM รวมถึง: การปรับปรุงประสิทธิภาพการซิงโครไนซ์และคอมไพเลอร์อัลกอริทึมใหม่และการอัพเกรดอัลกอริทึมการรวบรวมขยะที่มีอยู่และประสิทธิภาพการเริ่มต้นแอปพลิเคชัน

เกี่ยวกับมัน. Java SE 7.0 ดูน่าสนใจยิ่งขึ้น แต่ยังไม่วางจำหน่าย

เมื่อพิจารณาจำนวนฟีเจอร์ภาษาและ API ใหม่ที่เพิ่มเข้ามาใน C # ใน 4 ปีที่ผ่านมาฉันค่อนข้างประหลาดใจ Sun / Oracle เกิดอะไรขึ้น


ซันตัดสินใจเปิดโอเพ่นซอร์ส Java นี่คืออีกสิ่งหนึ่งที่ทำให้มั่นใจได้ว่าไม่ว่าสิ่งที่ออราเคิลตัดสินใจที่จะทำเราก็ยังสามารถเรียกใช้ OpenJDK ในกล่องลินุกซ์ นั่นทำให้พวกเขาล่าช้าเพียง 18-24 เดือน ...

@ Thorbjørn - อาจอธิบายได้ มันเป็นความอัปยศที่เกิดจากการหยุดชะงักของการซื้อนี้ ฉันเดาว่า C # สนุกกับการเปรียบเทียบเสถียรภาพ: เรามี lambdas ตั้งแต่ปี 2549 ที่ซึ่งดูเหมือนว่าพวกเขาจะไม่เข้าสู่ Java จนถึงปี 2012 ในขณะนี้
sheikhjabootie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.