คลาสภายในที่ไม่ระบุชื่อถูกใช้ใน Java อย่างไร


309

การใช้คลาสที่ไม่ระบุชื่อใน Java คืออะไร? เราสามารถพูดได้ว่าการใช้คลาสที่ไม่ระบุชื่อเป็นหนึ่งในข้อดีของ Java หรือไม่?


67
มันไม่ได้เป็นข้อได้เปรียบของจาวามากนักเนื่องจากเป็นวิธีการแก้ปัญหาการขาดการปิดจาวาใน
Eric Wilson

4
Java 8 ได้แนะนำแลมบ์ดานิพจน์เช่นกัน ตรวจสอบคำตอบ: stackoverflow.com/questions/355167/…
akhil_mittal

คำตอบ:


369

โดย "ชั้นไม่ระบุชื่อ" ฉันจะเอามันที่คุณหมายถึงระดับชั้นที่ไม่ระบุชื่อ

คลาสภายในที่ไม่ระบุชื่ออาจมีประโยชน์เมื่อสร้างอินสแตนซ์ของวัตถุที่มี "ความพิเศษ" บางอย่างเช่นวิธีการเอาชนะโดยไม่ต้องคลาสย่อยจริง ๆ

ฉันมักจะใช้เป็นทางลัดสำหรับการแนบ listener เหตุการณ์:

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // do something
    }
});

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

ฉันใช้เทคนิคนี้สำหรับงานที่ "เร็วและสกปรก" เท่านั้นซึ่งทำให้ทั้งชั้นรู้สึกว่าไม่จำเป็น การมีคลาสภายในที่ไม่ระบุชื่อหลายคลาสที่ทำสิ่งเดียวกันควรได้รับการปรับโครงสร้างให้เป็นคลาสจริงไม่ว่าจะเป็นคลาสภายในหรือคลาสที่แยกต่างหาก


5
หรือคุณสามารถ refactor คลาสภายในที่ไม่ระบุชื่อที่ซ้ำกันเป็นวิธีการเดียวกับคลาสภายในที่ไม่ระบุชื่อ (และอาจเป็นรหัสที่ซ้ำกันอื่น ๆ )
Tom Hawtin - tackline

3
คำตอบที่ดี แต่เป็นคำถามที่รวดเร็ว หมายความว่า Java สามารถอยู่ได้โดยไม่ต้องมีคลาสภายในที่ไม่ระบุชื่อและพวกมันเป็นตัวเลือกพิเศษให้เลือก
realPK

5
อธิบายได้ดีมากแม้ฉันจะขอแนะนำให้ทุกคนที่อ่านข้อความนี้เพื่อค้นหาและดูว่านิพจน์ของ java 8 และแลมบ์ดาสามารถทำอะไรได้บ้างเพื่อให้การเข้ารหัสเร็วและอ่านง่ายขึ้น
Pievis

2
@ user2190639 แม่นยำไม่สามารถขออะไรได้ดีกับแลมบ์ดาใน Java8
bonCodigo

3
ทำไมคุณถึงพูดoverloading methodsและไม่overriding methods?
Tarun

73

คลาสภายในที่ไม่ระบุชื่อนั้นปิดอย่างมีประสิทธิภาพดังนั้นจึงสามารถใช้เพื่อเลียนแบบแลมบ์ดานิพจน์หรือ "ผู้รับมอบสิทธิ์" ตัวอย่างเช่นใช้อินเทอร์เฟซนี้:

public interface F<A, B> {
   B f(A a);
}

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

public static int larger(final List<Integer> ns, final int i) {
  for (Integer n : ns)
     if (n > i)
        return n;
  return i;
}

จากนั้นคุณมีวิธีอื่นที่ส่งกลับหมายเลขแรกที่น้อยกว่า i ในรายการที่กำหนดหรือถ้าไม่มีจำนวนใดจะน้อยกว่า:

public static int smaller(final List<Integer> ns, final int i) {
   for (Integer n : ns)
      if (n < i)
         return n;
   return i;
}

วิธีการเหล่านี้เกือบจะเหมือนกัน ด้วยการใช้ฟังก์ชั่นเฟิร์สคลาสประเภท F เราสามารถเขียนสิ่งเหล่านี้เป็นวิธีการหนึ่งดังนี้:

public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) {
   for (T t : ts)
      if (f.f(t))
         return t;
   return z;
}

คุณสามารถใช้คลาสที่ไม่ระบุชื่อเพื่อใช้เมธอด firstMatch:

F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> {
   Boolean f(final Integer n) {
      return n > 10;
   }
};
int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x);

นี่เป็นตัวอย่างที่คาดการณ์ไว้จริง ๆ แต่มันง่ายที่จะเห็นว่าการส่งผ่านฟังก์ชั่นราวกับว่ามันเป็นค่าเป็นคุณสมบัติที่มีประโยชน์มาก โปรดดูที่"ภาษาการเขียนโปรแกรมของคุณสามารถทำได้"โดย Joel เอง

ไลบรารีที่ดีสำหรับการเขียนโปรแกรม Java ในรูปแบบนี้: Functional Java


20
โชคไม่ดีที่ความฟุ้งซ่านของการทำโปรแกรมฟังก์ชั่นในจาวา, IMHO นั้นมีค่าเกินกว่าข้อดี - หนึ่งในจุดที่โดดเด่นของการเขียนโปรแกรมเชิงฟังก์ชั่นคือมันมีแนวโน้มที่จะลดขนาดรหัสและทำให้อ่านและแก้ไขได้ง่ายขึ้น แต่จาวาฟังก์ชั่นดูเหมือนจะไม่ทำอย่างนั้นเลย
Chii

27
ความเข้าใจในการเขียนโปรแกรมฟังก์ชั่นทั้งหมดด้วยความอดทนของ Java!
Adam Jaskiewicz

3
จากประสบการณ์ของฉันรูปแบบการใช้งานใน Java นั้นถูกจ่ายออกมาอย่างละเอียด แต่ก็ให้ผลที่สั้นในระยะยาว ตัวอย่างเช่น myList.map (f) มีความละเอียดมากน้อยกว่า for-loop ที่เกี่ยวข้อง
Apocalisp

2
Scalaเป็นภาษาสไตล์การเขียนโปรแกรมที่ใช้งานได้ทำงานได้ดีภายใน JVM และอาจเป็นตัวเลือกสำหรับสถานการณ์การเขียนโปรแกรมเชิงฟังก์ชัน
Darrell Teague

51

คลาสภายในแบบไม่ระบุชื่อถูกใช้ในสถานการณ์ต่อไปนี้:

1. ) สำหรับการเอาชนะ (การจัดหมวดหมู่ย่อย) เมื่อการกำหนดคลาสไม่สามารถใช้งานได้ยกเว้นกรณีปัจจุบัน:

class A{
   public void methodA() {
      System.out.println("methodA");
    }
}
class B{
    A a = new A() {
     public void methodA() {
        System.out.println("anonymous methodA");
     }
   };
}

2. ) สำหรับการนำอินเตอร์เฟสไปใช้เมื่อต้องการการนำอินเตอร์เฟสไปใช้งานสำหรับกรณีปัจจุบันเท่านั้น:

interface interfaceA{
   public void methodA();
}
class B{
   interfaceA a = new interfaceA() {
     public void methodA() {
        System.out.println("anonymous methodA implementer");
     }
   };
}

3. ) อาร์กิวเมนต์ของคลาสภายในที่ไม่ระบุชื่อ:

 interface Foo {
   void methodFoo();
 }
 class B{
  void do(Foo f) { }
}

class A{
   void methodA() {
     B b = new B();
     b.do(new Foo() {
       public void methodFoo() {
         System.out.println("methodFoo");
       } 
     });
   } 
 } 

8
คำตอบที่ดีดูเหมือน 3) เป็นรูปแบบที่ใช้สำหรับผู้ฟังกิจกรรม
xdl

47

บางครั้งฉันใช้พวกเขาเป็นแฮ็กไวยากรณ์สำหรับการเริ่มต้นแผนที่

Map map = new HashMap() {{
   put("key", "value");
}};

VS

Map map = new HashMap();
map.put("key", "value");

มันช่วยประหยัดความซ้ำซ้อนเมื่อทำงบจำนวนมาก อย่างไรก็ตามฉันยังพบปัญหาในการทำเช่นนี้เมื่อคลาสภายนอกต้องได้รับการทำให้เป็นอนุกรมผ่าน remoting


56
เพื่อให้ชัดเจนชุดวงเล็บปีกกาแรกคือคลาสภายในที่ไม่ระบุชื่อ (subclassing HashMap) การจัดฟันชุดที่สองเป็นเครื่องมือเริ่มต้นอินสแตนซ์ (แทนที่จะเป็นชุดคงที่) ซึ่งจะตั้งค่าในคลาสย่อย HashMap ของคุณ +1 สำหรับการกล่าวถึง -1 สำหรับการไม่สะกดคำสำหรับ noobs ;-D
Spencer Kormos

4
อ่านเพิ่มเติมเกี่ยวกับไวยากรณ์ดับเบิลรั้งที่นี่
Martin Andersson


18

พวกเขามักใช้เป็นรูปแบบของการโทรกลับ verbose

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

นี่คือตัวอย่างการแกว่ง

myButton.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        // do stuff here...
    }
});

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


1
คุณหมายถึงพูดสั้น ๆ ? ถ้ามันเป็น verbose การโทรกลับจะอยู่แยกกันทำให้มันใหญ่ขึ้นเล็กน้อยและทำให้เป็น verbose ถ้าคุณบอกว่านี่ยังเป็น verbose สิ่งที่จะเป็นรูปแบบสั้น ๆ แล้ว?
3081519

1
@ user3081519 บางอย่างเช่นmyButton.addActionListener(e -> { /* do stuff here */})หรือmyButton.addActionListener(stuff)จะเป็น terer
ซามูเอลเอ็ดวินวอร์ด

8

คุณใช้มันในสถานการณ์ที่คุณจำเป็นต้องสร้างคลาสเพื่อวัตถุประสงค์เฉพาะภายในฟังก์ชั่นอื่นเช่นในฐานะผู้ฟังเป็น runnable (เพื่อวางไข่เธรด) ฯลฯ

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

พวกเขาเป็นน้ำตาล syntactic เป็นหลักและโดยทั่วไปควรจะย้ายไปที่อื่นเมื่อพวกเขาเติบโตที่ใหญ่กว่า

ฉันไม่แน่ใจว่ามันเป็นหนึ่งในข้อดีของ Java แต่ถ้าคุณใช้พวกเขา (และเราทุกคนใช้พวกเขาโชคไม่ดี) แล้วคุณสามารถยืนยันว่าพวกเขาเป็นหนึ่ง


6

GuideLines สำหรับ Class Anonymous

  1. คลาสที่ไม่ระบุชื่อถูกประกาศและเริ่มต้นพร้อมกัน

  2. คลาสที่ไม่ระบุชื่อต้องขยายหรือนำไปใช้กับหนึ่งหรือหนึ่งคลาสเท่านั้น

  3. คลาส anonymouse ไม่มีชื่อจึงสามารถใช้ได้เพียงครั้งเดียว

เช่น:

button.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
});

เกี่ยวกับ # 3: ไม่จริงทั้งหมด ref.getClass().newInstance()คุณสามารถได้รับกรณีหลายชั้นที่ไม่ระบุชื่อกับการสะท้อนเช่น
icza

กฎไม่ตอบคำถาม
มาร์ควิสแห่ง Lorne

5

ใช่คลาสภายในที่ไม่ระบุชื่อเป็นหนึ่งในข้อดีของ Java อย่างแน่นอน

ด้วยคลาสภายในที่ไม่ระบุชื่อคุณจะสามารถเข้าถึงตัวแปรสุดท้ายและตัวแปรสมาชิกของคลาสที่ล้อมรอบได้และนั่นมีประโยชน์ในการฟัง ฯลฯ

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


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

5
new Thread() {
        public void run() {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Exception message: " + e.getMessage());
                System.out.println("Exception cause: " + e.getCause());
            }
        }
    }.start();

นี่เป็นหนึ่งในตัวอย่างสำหรับประเภท Inner ที่ไม่ระบุชื่อโดยใช้เธรด


3

ฉันใช้วัตถุที่ไม่ระบุชื่อเพื่อโทรเข้าเธรดใหม่ ..

new Thread(new Runnable() {
    public void run() {
        // you code
    }
}).start();

3

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

ลองพิจารณาตัวอย่างจากdocที่เรามีPersonคลาส:

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}

และเรามีวิธีพิมพ์สมาชิกที่ตรงกับเกณฑ์การค้นหาดังนี้:

public static void printPersons(
    List<Person> roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}

CheckPersonอินเตอร์เฟสอยู่ที่ไหน:

interface CheckPerson {
    boolean test(Person p);
}

ตอนนี้เราสามารถใช้คลาสที่ไม่ระบุชื่อซึ่งใช้อินเทอร์เฟซนี้เพื่อระบุเกณฑ์การค้นหาเป็น:

printPersons(
    roster,
    new CheckPerson() {
        public boolean test(Person p) {
            return p.getGender() == Person.Sex.MALE
                && p.getAge() >= 18
                && p.getAge() <= 25;
        }
    }
);

ที่นี่อินเทอร์เฟซง่ายมากและไวยากรณ์ของคลาสที่ไม่ระบุชื่อดูเหมือนเทอะทะและไม่ชัดเจน

Java 8ได้เปิดตัวฟังก์ชั่นการใช้งานคำซึ่งเป็นอินเตอร์เฟซที่มีเพียงนามธรรมวิธีหนึ่งดังนั้นเราสามารถพูดได้ว่าCheckPersonเป็นอินเตอร์เฟซการทำงาน เราสามารถใช้แลมบ์ดานิพจน์ซึ่งช่วยให้เราสามารถส่งผ่านฟังก์ชันเป็นอาร์กิวเมนต์เมธอดเป็น:

printPersons(
                roster,
                (Person p) -> p.getGender() == Person.Sex.MALE
                        && p.getAge() >= 18
                        && p.getAge() <= 25
        );

เราสามารถใช้ส่วนต่อประสานการทำงานมาตรฐานPredicateแทนส่วนต่อประสานCheckPersonซึ่งจะช่วยลดจำนวนรหัสที่ต้องการ


2

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


1

หนึ่งในการใช้งานที่สำคัญของการเรียนที่ไม่ระบุชื่อในชั้นการสรุปซึ่งเรียกว่าfinalizer ผู้ปกครอง ในโลกของ Java ที่ใช้วิธีการสุดท้ายควรหลีกเลี่ยงจนกว่าคุณจะต้องการจริงๆ คุณต้องจำไว้ว่าเมื่อคุณแทนที่เมธอด finalize สำหรับคลาสย่อยคุณควรเรียกใช้เสมอsuper.finalize()เช่นกันเพราะวิธีการสุดท้ายของซุปเปอร์คลาสจะไม่เรียกใช้โดยอัตโนมัติและคุณอาจมีปัญหากับหน่วยความจำรั่ว

ดังนั้นเมื่อพิจารณาข้อเท็จจริงที่กล่าวข้างต้นคุณสามารถใช้คลาสที่ไม่ระบุชื่อเช่น:

public class HeavyClass{
    private final Object finalizerGuardian = new Object() {
        @Override
        protected void finalize() throws Throwable{
            //Finalize outer HeavyClass object
        }
    };
}

การใช้เทคนิคนี้ช่วยให้คุณผ่อนคลายตัวคุณเองและนักพัฒนาซอฟต์แวร์คนอื่น ๆ เพื่อเรียกsuper.finalize()ใช้คลาสย่อยHeavyClassที่ต้องการวิธีการสรุป


1

คุณสามารถใช้คลาสที่ไม่ระบุชื่อด้วยวิธีนี้

TreeSet treeSetObj = new TreeSet(new Comparator()
{
    public int compare(String i1,String i2)
    {
        return i2.compareTo(i1);
    }
});

1

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

public abstract class TypeHolder<T> {
    private final Type type;

    public TypeReference() {
        // you may do do additional sanity checks here
        final Type superClass = getClass().getGenericSuperclass();
        this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
    }

    public final Type getType() {
        return this.type;
    }
}

หากคุณจะยกตัวอย่างคลาสนี้ด้วยวิธีที่ไม่ระบุชื่อ

TypeHolder<List<String>, Map<Ineger, Long>> holder = 
    new TypeHolder<List<String>, Map<Ineger, Long>>() {};

เช่นนั้น holderอินสแตนซ์จะมีคำจำกัดความที่ไม่ถูกลบประเภทที่ผ่าน

การใช้

สิ่งนี้มีประโยชน์มากสำหรับการสร้างเครื่องมือตรวจสอบ / deserializators นอกจากนี้คุณสามารถยกตัวอย่างประเภททั่วไปมีการสะท้อน(ดังนั้นหากคุณเคยต้องการที่จะทำnew T()ในรูปแบบ parametrized - คุณจะยินดีที่)

ข้อบกพร่อง / ข้อ จำกัด

  1. คุณควรส่งพารามิเตอร์ทั่วไปอย่างชัดเจน การไม่ทำเช่นนั้นจะนำไปสู่การสูญเสียพารามิเตอร์ประเภท
  2. การสร้างอินสแตนซ์แต่ละครั้งจะทำให้คุณต้องเสียค่าใช้จ่ายเพิ่มเติมในการสร้างโดยคอมไพเลอร์ซึ่งจะนำไปสู่การสูญเสีย classpath / jar bloating

1

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

import java.util.Scanner;
abstract class AnonymousInner {
    abstract void sum();
}

class AnonymousInnerMain {
    public static void main(String []k){
        Scanner sn = new Scanner(System.in);
        System.out.println("Enter two vlaues");
            int a= Integer.parseInt(sn.nextLine());
            int b= Integer.parseInt(sn.nextLine()); 
        AnonymousInner ac = new AnonymousInner(){
            void sum(){
                int c= a+b;
                System.out.println("Sum of two number is: "+c);
            }
        };
        ac.sum();
    }

}

1

ไม่ประสงค์ออกนามภายในชั้นจะใช้ในการสร้างวัตถุที่ไม่เคยจะถูกอ้างถึงอีกครั้ง มันไม่มีชื่อและถูกประกาศและสร้างในคำสั่งเดียวกัน สิ่งนี้ถูกใช้ในตำแหน่งที่ปกติคุณจะใช้ตัวแปรของวัตถุ คุณเปลี่ยนตัวแปรที่มีnewคำหลักที่เรียกร้องให้ผู้สร้างและภายในกำหนดชั้นและ{}

เมื่อเขียนเธรดโปรแกรมใน Java มักจะมีลักษณะเช่นนี้

ThreadClass task = new ThreadClass();
Thread runner = new Thread(task);
runner.start();

ผู้ThreadClassใช้ที่นี่จะเป็นผู้กำหนด คลาสนี้จะใช้Runnableอินเตอร์เฟสที่จำเป็นสำหรับการสร้างเธรด ในวิธี (เฉพาะวิธีการใน) จะต้องดำเนินการเช่นกัน เป็นที่ชัดเจนว่าการกำจัดThreadClassrun()RunnableThreadClassจะมีประสิทธิภาพมากขึ้นและนั่นคือเหตุผลว่าทำไมจึงมีคลาสภายในที่ไม่ระบุชื่อ

ดูรหัสต่อไปนี้

Thread runner = new Thread(new Runnable() {
    public void run() {
        //Thread does it's work here
    }
});
runner.start();

รหัสนี้จะแทนที่การอ้างอิงที่ทำtaskในตัวอย่างด้านบนสุด แทนที่จะมีคลาสแยกต่างหาก Anonymous Inner Class ภายในThread()Constructor ส่งคืนออบเจกต์ที่ไม่มีชื่อที่ใช้Runnableอินเทอร์เฟซและแทนที่run()เมธอด วิธีการrun()จะรวมคำสั่งที่อยู่ภายในซึ่งทำงานตามที่เธรดต้องการ

ตอบคำถามว่า Anonymous Inner Classes เป็นหนึ่งในข้อดีของ Java หรือไม่ฉันต้องบอกว่าฉันค่อนข้างแน่ใจเพราะฉันไม่คุ้นเคยกับภาษาการเขียนโปรแกรมหลายภาษาในขณะนี้ แต่สิ่งที่ฉันสามารถพูดได้ก็คือมันเป็นวิธีการเข้ารหัสที่รวดเร็วและง่ายขึ้น

ข้อมูลอ้างอิง: Sams สั่งสอนตัวเองด้วยจาวาในรุ่นที่ 21


0

ข้อดีอีกข้อหนึ่ง: ดัง
ที่คุณทราบว่า Java ไม่สนับสนุนการสืบทอดหลายอย่างดังนั้นหากคุณใช้คลาส kinda "Thread" เป็นคลาสที่ไม่ระบุชื่อคลาสยังมีพื้นที่ว่างเหลืออีกหนึ่งคลาสที่จะขยาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.