有多少人喜歡使用內(nèi)部類,我就問你累不累。閑話不多說。
在Java中,可以將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內(nèi)部類。內(nèi)部類分為:成員內(nèi)部類,局部內(nèi)部類,匿名內(nèi)部類,靜態(tài)內(nèi)部類。
1.成員內(nèi)部類。
public class A
{
private String aa;
class B
{
private String aa;
public String getAa()
{
return aa;
}
public void setAa(String aa)
{
this.aa = aa;
}
public void print()
{
System.out.println(aa);
System.out.println(A.this.aa);
}
}
public String getAa()
{
return aa;
}
public void setAa(String aa)
{
this.aa = aa;
}
public static void main(String[] args)
{
A test = new A();
test.aa = "hello world";
B b = test.new B();
b.aa = "hello java";
b.print();
}
}
hello java
hello world
類B像是類A的一個成員,類B稱為外部類。成員內(nèi)部類可以無條件訪問外部類的所有成員屬性和成員方法(包括private成員和靜態(tài)成員)
不過需要注意的是,當(dāng)成員內(nèi)部類擁有和外部類同名的成員變量或者方法時,會發(fā)生隱藏現(xiàn)象,即默認(rèn)情況下訪問的是成員內(nèi)部類的成員。如果要訪問外部類的同名成員,需要用下面的形式訪問。
外部類.this.成員變量
外部類.this.成員方法
2.局部內(nèi)部類
局部內(nèi)部類是定義在一個方法或者一個作用域里面的類,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的訪問僅限于方法內(nèi)或者該作用域內(nèi)。
略:貌似沒有看到別人這樣寫過代碼
3.匿名內(nèi)部類
匿名內(nèi)部類是你通向大神的道路上的一座大山。因為不是所有人都能搞定的。這個匿名內(nèi)部類在異步回調(diào)機制中使用的非常多,與js的回調(diào)函數(shù)有很多相似的地方。
我們知道Node.js中大部分請求響應(yīng)都是異步回調(diào)方式完成的,在編寫監(jiān)聽事件的代碼使用匿名內(nèi)部類不但方便,而且代碼比較容易維護(hù)。
public MQPushConsumer start() throws InterruptedException,
MQClientException
{
DefaultMQPushConsumer pushConsumer = new DefaultMQPushConsumer(
getConsumerGroup());
pushConsumer.setNamesrvAddr(getNameSrvAddr());
pushConsumer.subscribe(getTopic(), getSubExpression());
pushConsumer
.setConsumeMessageBatchMaxSize(getConsumeMessageBatchMaxSize());
pushConsumer
.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
pushConsumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeConcurrentlyContext context)
{
try
{
processMsg(msgs);
}
catch (Exception e)
{
logger.info("end consume::" + msgs.toString());
logger.error(e);
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
logger.info("Consumer Started.");
return pushConsumer;
}
這一段代碼是RocketMQ消費端監(jiān)聽是否有消息過來的代碼。這里面就是用了匿名內(nèi)部類。
注意:匿名內(nèi)部內(nèi)是不能有訪問修飾符合static修飾符的。
匿名內(nèi)部類是唯一一種沒有構(gòu)造器的類,因為沒有構(gòu)造器則使用范圍就變得很窄,大部分匿名內(nèi)部類都用于接口回調(diào)(所謂的回調(diào)就是把內(nèi)部類比作一個電話號碼,這個電話號碼是你給別人的,只有別人能夠打,你自己不能用自己的手機打,其他的號碼你還是可以打的)。匿名內(nèi)部類在編譯的時候由系統(tǒng)自動起名為Outter$1.class。一般來說,匿名內(nèi)部類用于繼承其他類或是實現(xiàn)接口,并不需要增加額外的方法,只是對繼承方法的實現(xiàn)或是重寫。
4.靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類也是定義在另一個類里面的類,只不過在類的前面多了一個關(guān)鍵字static。靜態(tài)內(nèi)部類是不需要依賴于外部類的,這點和類的靜態(tài)成員屬性有點類似,并且它不能使用外部類的非static成員變量或者方法,這點很好理解,因為在沒有外部類的對象的情況下,可以創(chuàng)建靜態(tài)內(nèi)部類的對象,如果允許訪問外部類的非static成員就會產(chǎn)生矛盾,因為外部類的非static成員必須依附于具體的對象