精华内容
下载资源
问答
  • Java:在匿名内部类中调用外部类方法
    2021-03-06 18:13:39

    后者更明确,如果内部类中存在相同的名称,则可以调用外部类方法。

    class OuterClass {

    void foo() { System.out.println("Outer foo"); }

    View.OnClickListener mListener1 = new View.OnClickListener() {

    void foo() { System.out.println("Inner foo"); }

    @Override public void onClick(View view) {

    foo(); //Calls inner foo

    OuterClass.this.foo(); //Calls outer foo

    }

    }

    View.OnClickListener mListener2 = new View.OnClickListener() {

    @Override public void onClick(View view) {

    foo(); //Calls outer foo

    OuterClass.this.foo(); //Calls outer foo

    }

    }

    }

    更多相关内容
  • 匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型 这里所说的“匿名内部类”主要是指在其外部类的成员方法内定义,同时完成实例化的类,若其访问该成员方法中的局部变量,局部变量必须要被...

    重点!重点!重!点

    匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型

    1. 这里所说的“匿名内部类”主要是指在其外部类的成员方法内定义,同时完成实例化的类,若其访问该成员方法中的局部变量,局部变量必须要被final修饰。
    2. 原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命周期。局部变量的生命周期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命周期与其它类一样:自创建一个匿名内部类对象,系统为该对象分配内存,直到没有引用变量指向分配给该对象的内存,它才会死亡(被JVM垃圾回收)。所以完全可能出现的一种情况是:成员方法已调用结束,局部变量已死亡,但匿名内部类的对象仍然活着。
    3. 如果匿名内部类的对象访问了同一个方法中的局部变量,就要求只要匿名内部类对象还活着,那么栈中的那些它要所访问的局部变量就不能“死亡”。
    4. 解决方法:匿名内部类对象可以访问同一个方法中被定义为final类型的局部变量。定义为final后,编译程序的实现方法:对于匿名内部类对象要访问的所有final类型局部变量,都拷贝成为该对象中的一个数据成员。这样,即使栈中局部变量已死亡,但被定义为final类型的局部变量的值永远不变,因而匿名内部类对象在局部变量死亡后,照样可以访问final类型的局部变量,因为它自己拷贝了一份,且与原局部变量的值始终一致。
    展开全文
  • (1)内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它, 而内部类试图访问外部方法中的局部变量时,外部方法的局部变量很可能已经不存在了,那么就得延续其生命,...

    1.什么是匿名内部类?

    匿名内部类是没有名字的内部类。

    2.对局部变量有要求具体如下:

    (1)内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它, 而内部类试图访问外部方法中的局部变量时,外部方法的局部变量很可能已经不存在了,那么就得延续其生命, 拷贝到内部类中,而拷贝会带来不一致性,从而需要使用final声明保证一致性。说白了,内部类会自动拷贝外部变量 的引用,为了避免:

    外部方法修改引用,而导致内部类得到的引用值不一致

    内部类修改引用,而导致外部方法 的参数值在修改前和修改后不一致。于是就用 final 来让该引用不可改变。

    (2)内部类通常都含有回调,引用那个匿名内部类的函数执行完了就没了,所以内部类中引用外面的局部变量需要 是final的,这样在回调的时候才能找到那个变量,而如果是外部类的成员变量就不需要是final的,因为内部类本身 都会含有一个外部类的引用(外部类.this),所以回调的时候一定可以访问到

    3.demo

    package com.example.demo.test;
    
    interface IPerson {
        int a = 1;
    
        void sleep();
    
    }
    
    /**
     * @description: 匿名内部类需要集成抽象类 或实现 接口,只是没有名字罢了,并且生成的对象只能用一次,要想用多次要单独写
     * @author:houqd
     * @time: 2021/8/3 14:57
     */
    
    public class Demo6 {
        public static void main(String[] args) {
            final int[] b = {2};
            final String[] str = {"aa"};
            final Integer[] i = {1};
    
            Person p = new Person() {
    
                @Override
                void eat() {
                    System.out.println("");
                }
            };
            IPerson p1 = new IPerson() {
                @Override
                public void sleep() {
                    str[0] = "bb";
                    i[0] = 2;
                }
            };
        }
    }
    
    abstract class Person {
        abstract void eat();
    }
    
    class Student extends Person {
        @Override
        void eat() {
    
        }
    }
    
    

    4.总结:

    匿名内部类需要继成抽象类 或实现 接口,只是没有名字罢了,并且生成的对象只能用一次,要想用多次要单独写

    展开全文
  • 从学习java的时候知道匿名内部类能访问外部类的变量,那为何呢。先从一个最简答的例子开始: public class InnerTest { private int num = 0; public static void main(String[] args) { InnerTest innerTest...

    从学习java的时候知道匿名内部类能访问外部类的变量,那为何呢。先从一个最简答的例子开始:

    public class InnerTest {
    	
    	private int num = 0;
    
    	public static void main(String[] args) {
    		InnerTest innerTest = new InnerTest();
    		innerTest.inner();
    	}
    	
    	public void inner() {
    		Thread thread = new Thread() {
    			public void run() {
    				System.out.println(num);
    			};
    		};
    		thread.start();
    	}
    
    }
    

    这个类会生成两个class文件
    在这里插入图片描述

    // Compiled from InnerTest.java (version 1.6 : 50.0, super bit)
    class inner.InnerTest$1 extends java.lang.Thread {
      
      // Field descriptor #6 Linner/InnerTest;
      final synthetic inner.InnerTest this$0;
      
      // Method descriptor #8 (Linner/InnerTest;)V
      // Stack: 2, Locals: 2
      InnerTest$1(inner.InnerTest arg0);
         0  aload_0 [this]
         1  aload_1 [arg0]
         2  putfield inner.InnerTest$1.this$0 : inner.InnerTest [10]
         5  aload_0 [this]
         6  invokespecial java.lang.Thread() [12]
         9  return
          Line numbers:
            [pc: 0, line: 1]
            [pc: 5, line: 13]
          Local variable table:
            [pc: 0, pc: 10] local: this index: 0 type: new inner.InnerTest(){}
      
      // Method descriptor #14 ()V
      // Stack: 2, Locals: 1
      public void run();
         0  getstatic java.lang.System.out : java.io.PrintStream [20]
         3  aload_0 [this]
         4  getfield inner.InnerTest$1.this$0 : inner.InnerTest [10]
         7  invokestatic inner.InnerTest.access$0(inner.InnerTest) : int [26]
        10  invokevirtual java.io.PrintStream.println(int) : void [32]
        13  return
          Line numbers:
            [pc: 0, line: 15]
            [pc: 13, line: 16]
          Local variable table:
            [pc: 0, pc: 14] local: this index: 0 type: new inner.InnerTest(){}
    
      Inner classes:
        [inner class info: #1 inner/InnerTest$1, outer class info: #0
         inner name: #0, accessflags: 0 default]
      Enclosing Method: #27  #41 inner/InnerTest.inner()V
    }
    

    反编译InnerTest.class

    public class inner.InnerTest {
      
      // Field descriptor #6 I
      private int num;
      
      // Method descriptor #8 ()V
      // Stack: 2, Locals: 1
      public InnerTest();
         0  aload_0 [this]
         1  invokespecial java.lang.Object() [10]
         4  aload_0 [this]
         5  iconst_0
         6  putfield inner.InnerTest.num : int [12]
         9  return
          Line numbers:
            [pc: 0, line: 3]
            [pc: 4, line: 5]
            [pc: 9, line: 3]
          Local variable table:
            [pc: 0, pc: 10] local: this index: 0 type: inner.InnerTest
      
      // Method descriptor #19 ([Ljava/lang/String;)V
      // Stack: 2, Locals: 2
      public static void main(java.lang.String[] args);
         0  new inner.InnerTest [1]
         3  dup
         4  invokespecial inner.InnerTest() [20]
         7  astore_1 [innerTest]
         8  aload_1 [innerTest]
         9  invokevirtual inner.InnerTest.inner() : void [21]
        12  return
          Line numbers:
            [pc: 0, line: 8]
            [pc: 8, line: 9]
            [pc: 12, line: 10]
          Local variable table:
            [pc: 0, pc: 13] local: args index: 0 type: java.lang.String[]
            [pc: 8, pc: 13] local: innerTest index: 1 type: inner.InnerTest
      
      // Method descriptor #8 ()V
      // Stack: 3, Locals: 2
      public void inner();
         0  new inner.InnerTest$1 [27]
         3  dup
         4  aload_0 [this]
         5  invokespecial inner.InnerTest$1(inner.InnerTest) [29]
         8  astore_1 [thread]
         9  aload_1 [thread]
        10  invokevirtual java.lang.Thread.start() : void [32]
        13  return
          Line numbers:
            [pc: 0, line: 13]
            [pc: 9, line: 18]
            [pc: 13, line: 19]
          Local variable table:
            [pc: 0, pc: 14] local: this index: 0 type: inner.InnerTest
            [pc: 9, pc: 14] local: thread index: 1 type: java.lang.Thread
      
      // Method descriptor #40 (Linner/InnerTest;)I
      // Stack: 1, Locals: 1
      static synthetic int access$0(inner.InnerTest arg0);
        0  aload_0 [arg0]
        1  getfield inner.InnerTest.num : int [12]
        4  ireturn
          Line numbers:
            [pc: 0, line: 5]
    
      Inner classes:
        [inner class info: #27 inner/InnerTest$1, outer class info: #0
         inner name: #0, accessflags: 0 default]
    }
    

    可知这个类InnerTest$1持有了InnerTest的对象,具体在调用run方法的时候,会调用InnerTest.class中的静态方法 static synthetic int access$0(inner.InnerTest arg0);用对象arg0访问私有变量num.

    展开全文
  • 别嵌套的类称为内部类(inner class),嵌套其他类的的类称为外部类(outer class)。是我们类的第五大成员(属性,方法,构造器,代码块,内部类),内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类...
  • 我们参考大佬的这篇文章中引用的例子,来看一下匿名内部类访问外部变量的方法: public class Hello { public static void main(String[] args) { String str="haha"; new Thread() { @Override ...
  • 匿名内部类及如何访问外部变量

    千次阅读 2018-08-17 19:27:00
    4、匿名内部类如何访问在其外面定义的变量:匿名内部类不能访问外部类方法中的局部变量,除非该变量被声明为final类型 这里所说的“匿名内部类”主要是指在其外部类的成员方法内定义的同时完...
  • Java匿名内部访问外部类的局部变量,那么这个局部变量需要用final修饰吗? 为什么我的测试没有用final却可以?
  • Java匿名内部类使用外部参数

    千次阅读 2018-07-25 19:05:23
    jdk1.5 匿名内部类使用外部参数要用final 修饰外部参数 jdk1.8 匿名内部类使用外部参数不需要使用final 修饰外部参数  
  • ``` package 线程优先级; import java.awt.*;...如果不用静态变量的话我又不知道怎么在Runnable的匿名内部类访问外部循环的i,有没有什么办法在匿名内部类中能够访问外部的参数,而且不是常量不是静态变量?
  • https://www.cnblogs.com/DarrenChan/p/5738957.html
  • 看到标题,有一种很熟悉的感觉,我相信只要有几个月开发经验的人,总会遇到一个问题:匿名内部类访问的局部变量,必须用final修饰,要不然编译不通过。很多人都知道需要加final,但是这是为什么呢? 原因 一句话...
  • 为什么在匿名内部类中引用外部对象要加final修饰符呢,因为,在匿名内部类中引用的外部对象受到外部线程的作用域的制约有其特定的生命周期,以线程为例,当外部的变量生命周期已经完结之后,内部的线程还在运行,...
  • 1,Java中的匿名内部类是如何实现的? 先定义一个接口: 1 2 3 public interface MyInterface { void doSomething(); } 然后创建这个接口的匿名子类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
  • 如果定义一个匿名内部类,并且希望它使用一个在其外部定的对象,那么编译器会要求其参数引用是final的。 1.匿名内部类肯定是局部内部类(在一个方法里面定义...3.内部类很微妙,它可以直接访问外部类的privat
  • 内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。 这样理解就很容易得出为什么要用final了...
  • 爱Java 2016-11-06 22:46 对于Java语言中的final使用,大家应该很熟悉,可以修饰,表示不可继承;可以修饰方法,表示不可...Java编程中,使用匿名内部类访问外部方法的局部变量是一件很常见的事件,比如以下代码
  • 在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包括四种:成员内部类,局部内部类,匿名内部类,静态内部类 。 1.成员内部类 (1)该类像是外部类的一个...
  • 匿名内部类内部,方法和作用域内的内部内部使用的外部变量必须是 final 的是为什么?
  • 1.什么是匿名内部类 定义 : 1.匿名内部类是定义在类的局部位置,如方法中、代码块中,且没有明确的类名; 2.是一个内部类,本质还是一个类; 3.没有类名;...匿名内部访问 外部类的成员的方式
  • 原文地址 ... ...对于Java语言中的final使用,大家应该很熟悉,可以修饰类,表示不...那么,Java匿名内部访问外部类的局部变量,为何需被标志为final?这跟上述三个特性有关系吗? 一、问题的提出 Java编
  • 注意:在内部类构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,所以内部类会持有一个其外部类的引用。当内部类调用外部类的私有属性时,其真正的执行是调用了编译器生成的属性的静态方法(即acess...
  • 这里所说的“匿名内部类”主要是指在其外部类的成员方法内定义,同时完成实例化的类,若其访问该成员方法中的局部变量,局部变量必须要被final修饰。 原因是编译程序实现上的困难:内部类对象的生命周期会超过局部...
  • 由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。  不过你可能要质疑,更改一下方法的不行了吗?  的确,以此作为设计内部类的理由,实在没有说服力。  真正的...
  • 匿名内部类

    千次阅读 多人点赞 2018-09-22 14:12:02
    个人觉得用陈国君主编的《Java程序设计基础(第五版)》中的 “所谓匿名内部类,是指可以利用内部创建没有名称的对象,它一步完成了声明内部和创建该的一个对象,并利用该对象访问里面的成员”来描述,或许...
  • 之前在1.6的环境下写直接使用外部变量编译器会提示必须要有final修饰,《Think in java》有这一段: If you’re defining an anonymous inner class and want to use an object that’s defined outside the ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 96,315
精华内容 38,526
关键字:

匿名内部类访问外部