<commit_before>---
layout: post
title:  "接口可以直接new？"
date:   2015-04-21 9:25:32
categories: java
tags: java
mathjax: true
---

看到标题，不免让人心生怀疑。接口难道可以new？  
我们知道接口本身是用来定义标准的，具体实现由实现类来填充，使用的时候我们再实例化对应的接口的实现类。  
严格来说，接口不能new。  
但是我们可以通过匿名内部类的方式，无需创建独立的实现类，完成接口的实现。  
比如我们常用的实现`Runnable`接口启动线程的方式：
```java
new Thread(new Runnable(){
    @Override
    public void run(){
        ......
    }
}).start();
```
这样的写法，大大的简化了我们的代码，否则，我们需要单独定义`Runnable`的实现类。  
还有我们常用的动态代理，其实也可以使用匿名内部类的方式，正常情况下我们定义InvocationHandler的实现类，进行代理方法invoke方法的重写。实际上我们完全可以通过下面的代码实现：
```java
Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
            //..........
            }
}
```
这样，我们就省去了InvocationHandler接口实现类的开销。

实际上在我们的类编译class的时候，匿名内部类也是单独编译成class文件的，见下图：
![image_1binq5fj7u38jaor7g1137b1q9.png-15.5kB][1]  
我们对匿名内部类进行反编译：
### RpcFramework$1.class
```java
package com.lxy.rpc.framework;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;<commit_msg>Update 2015-04-21-接口可以直接new？.md<commit_after>---
layout: post
title:  "接口可以直接new？"
date:   2015-04-21 9:25:32
categories: java
tags: java
mathjax: true
---

看到标题，不免让人心生怀疑。接口难道可以new？  
我们知道接口本身是用来定义标准的，具体实现由实现类来填充，使用的时候我们再实例化对应的接口的实现类。  
严格来说，接口不能new。  
但是我们可以通过匿名内部类的方式，无需创建独立的实现类，完成接口的实现。  




比如我们常用的实现`Runnable`接口启动线程的方式：
```java
new Thread(new Runnable(){
    @Override
    public void run(){
        ......
    }
}).start();
```
这样的写法，大大的简化了我们的代码，否则，我们需要单独定义`Runnable`的实现类。  
还有我们常用的动态代理，其实也可以使用匿名内部类的方式，正常情况下我们定义InvocationHandler的实现类，进行代理方法invoke方法的重写。实际上我们完全可以通过下面的代码实现：
```java
Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {
            //..........
            }
}
```
这样，我们就省去了InvocationHandler接口实现类的开销。

实际上在我们的类编译class的时候，匿名内部类也是单独编译成class文件的，见下图：
![image_1binq5fj7u38jaor7g1137b1q9.png-15.5kB][1]  
我们对匿名内部类进行反编译：
### RpcFramework$1.class
```java
package com.lxy.rpc.framework;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
{'fraction_non_alphanumeric': 0.13562925170068027, 'fraction_numerical': 0.02891156462585034, 'mean_word_length': 4.972081218274112, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4431621', 'n_tokens_mistral': 1273, 'n_tokens_neox': 1251, 'n_words': 126}