开发者

new Object { } Construct

开发者 https://www.devze.com 2023-01-15 11:01 出处:网络
In Java开发者_如何学运维, the standard way to create an object is using MyClass name = new MyClass();

In Java开发者_如何学运维, the standard way to create an object is using

MyClass name = new MyClass();

I also often see the construct

new MyClass() { /*stuff goes in here*/ };

I've been looking online for a while and can't find a good explanation of what the second construct style does or how it does it.

Can someone please explain how and why you would use the second construct?


This construct makes actually two things: 1) It declares an anonymous class which extends the class you use in the constructor and 2) creates an instance of this anonymous class.

Edit: When using such a construct you can observe the anonymous class by looking at the generated .class files. There is the normal MyClass.class file and another one for each anonymous subclass: MyClass$1.class for the first and so on.


You would use the second construct in the case that you want to make an anonymous class. if you have a method that takes a callback as an argument, you might want to specify the implementation of the callback inline as opposed to giving it a name and putting it in a separate file or declaring it elsewhere in the same file.

There's also a trick called double brace initialization where you can get around not having syntax for literal maps and lists by using anonymous classes, like this:

Map map = new HashMap() {{put("foo", 1); put("bar", 2);}};

Here the nested braces create an instance initializer. The object bound to map is not a HashMap, its class is an anonymous class extending HashMap. (That means if you have a PMD rule about classes needing to declare serial uids then it will complain about this.)

Double-brace initialization is a fun trick to know but don't use it in real code. It's not safe to pass around the map created like this, because the inner object keeps a reference to the outer instance so if anything in the program holds onto a reference to the map it keeps the outer object from getting garbage-collected. There are also problems with serialization.


As others have already said, it creates an instance of an anonymous class, subclassing Class. Here's an example how it is commonly used:

panel.addMouseListener(
  new MouseAdapter () {
    @Override
    public void mouseEntered(MouseEvent e) {
      System.out.println(e.toString());
    }
  }
);

The above code creates an instance of an anonymous class which extends MouseAdapter. In the anonymous class the method mouseEntered has been overridden to demonstrate that the anonymous class works basically as any other class. This is very convenient and common way to create (usually simple) listeners.


Second construction creates an instance of anonymous class which is a subclass of Class.


If you want to new a object by a protect constructor from another package, you can use:

new Foo() {};

otherwise you will get an access error. It equals anonymous subclass inherited from Foo class.


From jdk8 onwards you may have seen different syntax seems like creating an objects while using lambda expressions.

NOTE: Lambda expressions don't get translated into anonymous inner classes, they use invoke dynamic that was introduced in Java 7 to execute functional methods.

For Example:

public class LambdaSample {

    public static void main(String[] args) {
        //If implementation is only one statement then {} braces are optional
        Runnable oneLineImplRunnable = ()->System.out.println("This is one line lambda expression");
        //Multiple statements in the implementation then {} braces are mandatory
        Comparator<StudentTest> stdComparator = (StudentTest s1,StudentTest s2)->{
            if(s1.getFirstName().equals(s2.getFirstName())) {
                return s1.getLastName().compareTo(s2.getLastName());
            }else {
                return s1.getFirstName().compareTo(s2.getFirstName());
            }
        };
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消