java 遍历所有内部类_聊聊Java内部类

一.磨叽磨叽Java值传递与引用传递

“在Java里面参数传递都是按值传递”

即:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

简单的说,基本数据类型是按值传递的,方法的实参是一个原值的复本。类对象是按对象的引用地址(内存地址)传递地址的值,那么在方法内对这个对象进行修改是会直接反应在原对象上的(或者说这两个引用指向同一内存地址)。注意String也是值传递。

public static void main(String[] args) {

String x = new String("now");

User user = new User("now");

change(x);

System.out.println("1:"+x);

change(user);

System.out.println("2:"+user.name);

User user1 = new User("now");

System.out.println("3:"+user1 .name);

}

public static void change(String x) {

x = "even";

}

public static void change(User x) {

x.name = "even";

}

public static void change(User x) {

x = new User("even");

}

得出的结果

1:even

2:even

3:now

二.回归正题,聊聊Java内部类的这些事

Java允许在一个类里面定义另一个类,类里面的类就是内部类,也叫做嵌套类

简单的内部类如下:

class OuterClass {

class InnerClass{

}

}

经常用到的内部类:

public class PrivateToOuter {

Runnable mRunnable = new Runnable(){

private int x=10;

@Override

public void run() {

System.out.println(x);

}

};

}

以上代码mRunnable让人并不觉得是内部类,它并不像InnerClass那样形象,但是其实以下句柄实现一个继承Runable的类,也就是自定义了一个类,那么明显它就是一个内部类。其实它是属于内部类一种:匿名内部类Anonymous Inner Class

{

private int x=10;

@Override

public void run() {

System.out.println(x);

}

}

内部类需要注意的以下几点:

(1)内部类的获取

内部类可以访问包装他的外部类的所有,方法和属性,包括私有方法。但是对其他类来说,它是隐藏的,哪怕对同一个包下面其他类来说,内部类都是隐藏的,也就是说,如果要访问内部类,就必须先要得到他的外部包装类,得到那个句柄之后在new 内部类,就可以调用他的方法了,如下:

OuterClass outer = new OuterClass();

InnerClass innerClass = outer.new InnerClass();

所以内部类是可以很好的解决单继承的问题。如果对于private在此逻辑为何失效的话,可以查看细话Java:"失效"的private修饰符

(2)静态内部类

如果用static 将内部内静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性

class Out {

private static int age = 12;

private int time = 14;

static class In {

public void print() {

System.out.println(age);

}

}

}

public class Demo {

public static void main(String[] args) {

Out.In in = new Out.In();

in.print();

}

}

也就是说in只能访问age,而非time

(3)私有内部类

如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类

class Out {

private int age = 12;

private class In {

public void print() {

System.out.println(age);

}

}

public void outPrint() {

new In().print();

}

}

public class Demo {

public static void main(String[] args) {

//此方法无效

/*

Out.In in = new Out().new In();

in.print();

*/

Out out = new Out();

out.outPrint();

}

}

需要特别告诉大家重要的point就是:

在内部类构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,所以内部类会持有一个其外部类的引用。

在Java中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用。静态的内部类不会持有外部类的引用。所以point3中的内部类是无法获取到外部类的成员变量与方法。

回归到android:

public class SampleActivity extends Activity {

private final Handler handler= new Handler() {

@Override

public void handleMessage(Message msg) {

// ...

}

}

}

这是我们获取handler实例经常所做的操作,但是回归到point得知,handler的匿名内部类中有SampleActivity的引用,所以这是有可能导致OOM的隐患,比如以下代码:

public class SampleActivity extends Activity {

private final Handler mLeakyHandler = new Handler() {

@Override

public void handleMessage(Message msg) { // ... }

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mLeakyHandler.postDelayed(new Runnable() {

@Override

public void run() { /* ... */ }

}, 1000 * 60 * 10);

finish();

}

}

SampleActivity对象已经finish,但是mLeakyHandler的消息要在10分钟后执行操作,而Handler是一个匿名内部类的实例,其持有外面的SampleActivity的引用(而且Runable也是匿名内部类,其内部也是持有SampleActivity的引用),所以这导致了SampleActivity无法回收,进行导致SampleActivity持有的很多资源都无法回收,这就是我们常说的内存泄露。解决方法如下:

public class SampleActivity extends Activity {

private static class MyHandler extends Handler {

private final WeakReference mActivity;

public MyHandler(SampleActivity activity) {

mActivity = new WeakReference(activity);

}

@Override

public void handleMessage(Message msg) {

SampleActivity activity = mActivity.get();

if (activity != null) { // ... }

}

}

private final MyHandler mHandler = new MyHandler(this);

private static final Runnable sRunnable = new Runnable() {

@Override

public void run() { /* ... */ }

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mHandler.postDelayed(sRunnable, 1000 * 60 * 10);

finish();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值