精华内容
下载资源
问答
  • 局部内部类(方法内部类)
    2019-09-29 20:00:34

    局部内部类

    如果一个类是定义在一个方法内部,那么他就是一个局部内部类。
    //“局部”:只是当前所属的方法才能使用它,除了这个方法就不行了。
    /*定义格式:

    • 修饰符 class 外部类名称{//
    • 修饰符 返回值类型 外部类名称方法(参数列表)
    • {class 局部内名称{//}}}*/
      /*小结:
    • public >protected>(default)>private
    • 外部类:public/(default)
    • 成员内部类:public protected default private
    • 局部内部类:什么都不能写。 —*/

    局部内部类Outer
    代码:

     public class Outer {
    public void method()
    {
        class Inner{
            int num=10;
            //int num=20;
            public void methodinner()
            {
                System.out.println(num);
            }
        }
        Inner inner=new Inner();//只能在该方法中调用局部内部类的方法!
        inner.methodinner();
    
    }
    }
    

    主类:
    代码:

    public class Demo01Main {
    
    public static void main(String[] args) {
        Outer obj=new Outer();
          obj.method();
    }
    }
    

    注意事项:

    /*局部内部类,如果希望访问所在方法的变量局部,那么这个局部变量必须是final的

    • 备注:从java8开始,只要局部变量事实不变,那么final关键字可以省掉。
      原因(为什么用final修饰)
    • 1.new来出的对象在堆内存中
    • 2.局部变量跟着方法邹,在栈中
    • 3.方法运行结束后,立即出栈,局部变量就会消失。
    • 4.但是new出来的对象还在堆中,直到垃圾回收,如果上述过程执行完毕,对象还想调用局部变量的值,无法调用。所以使用final关键字来修饰。*/

    举例:
    代码:
    public class MyOuter {

    int num=10;
    public void method()
    {
        class Myinner
        {
           /*final*/
            int num=20;
           // num=30;无法更改,fianl定义了!
            public void methodinner()
            {
                System.out.println(MyOuter.this.num);//10
                  System.out.println(this.num);//20
            }
        }
        Myinner myinner=new Myinner();
        myinner.methodinner();
    }
    

    }

    更多相关内容
  • Java在嵌套类型这里提供的特性比较多,假设:Java的字节码只支持静态嵌套类,内部类、局部内部类和匿名局部内部类都是编译器提供的语法糖,这个假设目前没法验证(看不懂字节码),本文先来看一下C#是如何为我们提供...
  • 主要介绍了Java局部内部类和匿名内部类,结合实例形式分析了java局部内部类和匿名内部类相关定义、原理与用法,需要的朋友可以参考下
  • 主要介绍了Java局部内部类的相关资料,帮助大家更好的理解和学习Java 内部类的知识,感兴趣的朋友可以了解下
  • 主要介绍了Java局部内部类原理与用法,结合实例形式分析了Java局部内部类功能、用法及相关操作注意事项,需要的朋友可以参考下
  • java 局部内部类使用规范 java 局部内部类使用规范
  • 1.首先来了解一下局部内部类是如何访问局部变量的 Person类是外部类,LoInClassIntf是接口,localInClassRe是Person类的成员方法,且返回值类型为LoInClassIntf; 方法内定义了一个局部内部类LoInnerClass,该内部...

    1.首先来了解一下局部内部类是如何访问局部变量的

    Person类是外部类,LoInClassIntf是接口,localInClassRe是Person类的成员方法,且返回值类型为LoInClassIntf;

    方法内定义了一个局部内部类LoInnerClass,该内部类实现了接口LoInClassIntf;

    方法内还定义了一个final的局部变量a,定义了一个LoInnerClass类型的对象引用loInC;

    代码如下:

     1     //笔记23:内部类--局部内部类--实现接口,返回内部类对象
     2     //接口
     3     public interface LoInClassIntf {
     4         void test();
     5     }
     6 
     7     //方法localInClassRe,返回值为LoInClassIntf,局部内部类来实现该接口,向上转型
     8     public LoInClassIntf localInClassRe() {  
     9         final int a = 1; //常量
    10         
    11         //笔记23--内部类--局部内部类--实现接口
    12         class LoInnerClass implements LoInClassIntf {
    13             public void test() {
    14                 System.out.println("variable a:" + a);
    15             }
    16         }
    17 
    18         LoInnerClass loInC = new LoInnerClass();
    19         return loInC;
    20     }
    21 
    22     public static void main(String[] args) {
    23         //笔记23--局部内部类
    24         Person per = new Person();
    25         
    26         LoInClassIntf lInCIntf = per.localInClassRe();
    27         lInCIntf.test();
    28     }

     

    输出结果为:

    1 variable a:1

     

    成员方法localInClassRe执行中的内存示意图如下:

     

    成员方法localInClassRe执行后的内存示意图如下:

     

     

    分析:

        成员方法localInClassRe执行后,方法体中的局部变量a和对象引用loInC都被释放掉了,但分配在堆中的对象未回收,这时由main方法中的局部变量lInCIntf来指向它

        到这里还没什么问题,但第27行,lInCIntf调用了test方法,test方法中访问到了成员方法localInClassRe中的局部变量a,而a此时已不存在了,所以就会出现错误;

        即,局部变量与局部内部类的对象的生命周期不同;

        为解决这一问题,Java把局部内部类要访问的局部变量重新拷贝了一份,并把备份放在内部类的常量池中,这样不论方法有没有执行结束,拷贝都是存在的,就不会再出现访问不存在的变量的错误了。

     

    成员方法localInClassRe执行中的内存示意图如下:

     

    成员方法localInClassRe执行后的内存示意图如下:

     

     上面涉及到的局部变量a是方法体内定义的,如果局部内部类访问的是方法体的参数呢?

    Java采取的方法是,默认为局部内部类的构造方法传入该参数作为构造方法的参数,然后用该参数来初始化内部类中拷贝的变量a。

     

    局部内部类如何访问局部变量的问题解决了,那么为什么只能访问final的局部变量呢?

     

    2.数据同步的问题

    上面通过拷贝一份局部变量来解决生命周期不同的问题,如果方法体和局部内部类都改变了a的值会怎么样呢?

    如下图所示:

     

    这样两个a不一致,就会出现数据不同步,下一步应该用a=2还是a=3呢?

    为解决这个问题,Java规定局部内部类可访问的局部变量必须为final的,即内部类不能改变要访问的局部变量的值,这样就不会出现数据不同步的问题了

    原文转载自: http://www.cnblogs.com/chanchan/p/8402411.html 

    展开全文
  • java内部类之成员内部类、局部内部类和匿名内部类

    千次阅读 多人点赞 2018-07-15 16:13:30
    2、局部内部类(包含匿名内部类)。 成员内部类 定义格式: 修饰符 class 类名称 { 修饰符 class 类名称 { //... } //... } 注意: 内部类使用外部,可以随意访问,但是外部类使用内部类要借助内部类的对象...

    内部类概念

    一个类中包含另外一个类。

    分类

    1. 成员内部类。
    2. 局部内部类(包含匿名内部类)。

    成员内部类

    定义格式:

    修饰符 class 类名称 {
        修饰符 class 类名称 {
            //...
        }
        //...
    }

    注意:

    内部类使用外部,可以随意访问,但是外部类使用内部类要借助内部类的对象。

    使用成员内部类

    两种方法:
    1. 间接方式:在外部类的方法中,使用内部类,然后main只调用外部类的方法。
    2. 直接方式:公式:
    一般类:类名称 对象名 = new 类名称();
    成员内部类:外部内名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();

    Body.java含有一个内部类Heart

    public class Body {
    
        private String name;
    
        //外部类方法
        public void methodBody() {
            System.out.println("外部类的方法");
            new Heart().beat();//在外部类方法中使用内部类。 
        }
    
    
        public  class Heart { //成员内部类
            //内部类方法
            public void  beat() {
                System.out.println("心脏跳动");
                System.out.println("我叫:"+name);
            }
        }
    }

    下面分别介绍两种方式访问内部类:

    间接方式访问内部类

    Demo01InnerClass.java

    public class Demo01InnerClass {
        public static void main(String[] args) {
            Body body = new Body();//外部类对象
    
            //通过外部类的对象,调用外部类的方法,里面间接使用内部类Heart
            body.methodBody();

    直接方式访问内部类

    public class Demo01InnerClass {
        public static void main(String[] args) {
            Body body = new Body();//外部类对对象
    
            //外部内名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
            Body.Heart heart = new Body().new Heart();
            heart.beat();
        }
    }

    外部类和内部类变量重名问题

    当外部类的变量和内部类变量重名时,在内部类方法中访问外部类变量的格式是:外部类.this.外部类成员变量名

    public class Outer {
        int number = 10;
    
        public class Inner {
            int number = 20;
    
            public  void methodInner() {
                int number =30;//内部类方法的局部变量
                System.out.println(number);//就近原则
                System.out.println(this.number);
                System.out.println(Outer.this.number);//外部类的成员变量
            }
        }
    }

    30
    20
    10


    局部内部类

    如果类是定义在一个方法内部的,那么这就是一个局部内部类。
    “局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。

    定义格式

    修饰符 class 外部类名称 {
        修饰符 返回值类型  外部类方法名称(参数列表) {
            class 局部内部类名称 {
                //...
            }
        }
    }

    Outer.java含有局部内部类

    public class Outer {
        public void methodOuter() {
    
            class Inner {
                int num = 10;
                public void methodInner() {
                    System.out.println(num);//10
                }
            }
            //这个内部列只有当前所属方法能够访问这个类,出了这个方法就不能用了
            Inner inner = new Inner();
            inner.methodInner();
        }
    }

    DemoMain.java

    public class DemoMain {
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            outer.methodOuter();
        }
    }

    结果:
    10

    注意:

    局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】
    备注:从java 8+开始,只要局部变量事实不变,那么final关键字可以省略。
    原因:
    1. new 出来的对象在堆内存当中。
    2. 局部变量是跟着方法走的,在栈内存当中。
    3. 方法运行结束后,立刻出栈,局部变量就会立刻消失。
    4. 但是new出来的对象在堆当中持续存在,直到垃圾回收消失。

    public class MyOuter {
        public void methodOuter() {
            final int num = 10;//所在方法的局部变量
    
            /*在栈中的局部变量可能随着方法结束出栈消失了,但是创建的内部类对象还存在。
            对象使用常量时能直接将常量copy进来,这时就要保证这个常量是不可更改的,也就是final。
            */
            //num = 20;
    
            class MyInner {
                public  void methodInner() {
                    System.out.println(num);
                }
            }
            Inner myinner = new MyInner();
            inner.methodInner();
        }
    }

    修饰内部类的权限

    public > protected > (default) > private
    定义一个类的时候,权限修饰符规则:

    1. 外部类:public / (default)
    2. 成员内部类:都可以写,public > protected > (default) > private
    3. 局部内部类:什么都不能写,但不是de

    匿名内部类

    如果接口的实现类(或者是父类的子类)只需要使用唯一的一次。
    那么这种情况下就可以省略调该类的定义,而改为使用【匿名内部类】。

    匿名内部类定义格式:

    接口名称 对象名 = new 类名或者接口名称() {
        //覆盖重写所有抽象方法
    };

    代表继承了或者实现了该接口的子类对象。

    ==接口MyInterface.java==

    public interface MyInterface {
        void method1();//抽象方法
        void method2();
    }

    ==接口实现类MyInterfaceImp.java==

    public class MyInterfaceImpl implements  MyInterface {
    
    
        @Override
        public void method1() {
            System.out.println("实现类覆盖重写了方法1");
        }
    
        @Override
        public void method2() {
            System.out.println("实现了覆盖重写方法2");
        }
    }

    测试类

    一、一般接口实现方法

    DemoMain.java

    public class DemoMain {
        public static void main(String[] args) {
    //        MyInterface impl = new MyInterfaceImpl();
    //        impl.method();
            }
    }

    匿名内部类实现接口

    DemoMain.java

    public class DemoMain {
        public static void main(String[] args) {
    
            //使用匿名内部类,但不匿名对象,对象名称就叫obj
            MyInterface objA = new MyInterface() {
                @Override
                public void method1() {
                    System.out.println("匿名内部类实现了方法1-A");
                }
                @Override
                public void method2() {
                    System.out.println("匿名内部类实现了方法2-A");
                }
            };
            objA.method1();
            objA.method2();
    
            System.out.println("----------我是分割线----------");
    
            //使用匿名内部类,而且省略了对象名称,也是匿名对象
            new MyInterface() {
                @Override
                public void method1() {
                    System.out.println("匿名内部类实现了方法1-B");
                }
                @Override
                public void method2() {
                    System.out.println("匿名内部类实现了方法2-B");
                }
            }.method1();
        }
    }

    结果:
    匿名内部类实现了方法1-A
    匿名内部类实现了方法2-A
    ----------我是分割线----------
    匿名内部类实现了方法1-B

    匿名内部内应用

    • 实现倒计时5秒。
    public class Demo02_Time {
        public static void main(String[] args) {
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("倒计时5秒");
                }
            },5000);//倒计时5秒
        }
    }

    注意事项:

    对格式进行解析:"new 接口名称 {...};"进行解析

    1. new代表创建对象的动作
    2. 接口名称就是匿名内部类需要实现那个接口
    3. {…}这才是匿名内部类的内容

    注意:

    1. 这个类只需要使用一次。匿名内部类在创建对象时,只能使用唯一一次。
      如果希望多次希望多次创建对象,而且内容一样的话,那么就必须使用单独定义的实现类。

    2. 匿名对象,在调用的时候,只能调用唯一一次。
      如果希望同一个对象,调用多次方法,那么必须给对象取一个名字。

    3. 匿名内部类是省略了【实现类/子类】,但是匿名对象是省略了【对象命名】。

    强调:匿名和匿名对象不是一回事。

    展开全文
  • 内部类与局部内部类

    千次阅读 2018-08-19 08:31:22
    内部类与局部内部类 1、什么是内部类 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。 1.成员内部类 :定义在类中方法外的类。 定义格式:  class 外部类 {  class内部类{ } ...

    内部类与局部内部类

    1、什么是内部类

    将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。

    1.成员内部类 :定义在类中方法外的类。

    定义格式:

      class 外部类 {

             class内部类{

    }

    }       

     

    2.访问特点

    内部类可以直接访问外部类的成员,包括私有成员。 外部类要访问内部类的成员,必须要建立内部类的对象。

    创建内部类对象格式:    

    外部类名.内部类名 对象名=new 外部类名().new 内部类名()    

    举例代码:

    1.内部类

    package DemoTest.DemoTest2;
    public class person {
        private String name;
            public class xianren{
                public void XianShow(){
                    System.out.println("仙人模式!");
                    System.out.println("我叫"+name);
                }
            }

    public void show(){
            System.out.println("间接调用内部类!");
            xianren xr = new xianren();
            xr.XianShow();
        }

        public person() {
        }
        public person(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

    }

    2.测试类

    package DemoTest.DemoTest2;

    public class Test {
        public static void main(String[] args) {

    //第一种调用方法
            person p = new person();
            p.setName("鸣人");
            p.show();
            System.out.println("========================");

    //第二种调用方法
            person.xianren x = p.new xianren();
            x.XianShow();
            System.out.println("========================");

    //第三种调用方法
            //外部类名.内部类名 对象名=new 外部类名().new 内部类名()
            person.xianren obj= new person("鸣人").new xianren();
            obj.XianShow();
        }
    }

    3.结果:

    间接调用内部类!

    仙人模式!

    我叫鸣人

    ========================

    仙人模式!

    我叫鸣人

    ========================

    仙人模式!

    我叫鸣人

     

    举例代码2:

    获取不同地址的值

    1.不同位置的num
    public class Denoquzhi {
        int num=10;
        class Quzhi{
            int num=20;
            public void print(){
                int num=30;
                System.out.println(num);
                System.out.println(this.num);
                System.out.println(Denoquzhi.this.num);
            }
        }
        public void da(){
            System.out.println("间接调用");
            Quzhi q = new Quzhi();
            q.print();
        }
    }

    2.测试类

    package DemoTest.Demoquzhi;

    public class Teat {
        public static void main(String[] args) {

    //间接调用
            Denoquzhi d = new Denoquzhi();
            d.da();
            System.out.println("===================");

    //格式规定的直接调用
            Denoquzhi.Quzhi dui=new Denoquzhi().new Quzhi();
            dui.print();
        }
    }

    3.结果:

    间接调用

    30

    20

    10

    ===================

    30

    20

    10

     

    2、局部内部类

    举例代码:

    1.在类的方法内包含了一个内部类

    package DemoTest.DemoSamill;

    public class Demosamill {
        public void method(){
            class MethodClass{
                int num=10;
                public void print(){
                    System.out.println("局部内部类");
                    System.out.println(num);
                }
            }
            MethodClass m = new MethodClass();
            m.print();
        }
    }

    2.测试类

    package DemoTest.DemoSamill;

    public class Test {
        public static void main(String[] args) {
            Demosamill d = new Demosamill();
            d.method();
        }
    }

    3.结果

    局部内部类

    10

     

     

     

     

     

    展开全文
  • 内部类详解————局部内部类

    千次阅读 多人点赞 2018-05-05 23:10:07
    《内部类详解————局部内部类》 《内部类详解————静态嵌套类》 定义 在方法或某个作用域内的内部类,称为局部内部类。匿名内部类就是一种局部内部类。 实现方式 public class OutterType { public ...
  • 因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的...加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。 ...
  • Java ---- 局部内部类 静态内部类 普通内部类
  • Java 局部内部类、匿名内部类详解

    千次阅读 2019-08-19 00:34:02
    外部类与内部类 众所周知,每个java文件必须有一个与这个java文件同名的外部类,这个外部类可以是public或default的。而除了这个同名外部类,还可以有与这个同名外部类平级的其他外部类,但它们必须是default的。 而...
  • * 局部内部类访问局部变量必须用final修饰* 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么? 因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,...
  • Java基础_内部类静态内部类成员内部类局部内部类匿名内部类 内部类 使用内部类减少了命名冲突 一个内部类可以定义在一个类中一个方法中甚至一个表达式中 内部类分为四种 静态内部类(static inner classes) 成员内部...
  • 1 内部类的概念 内部类是定义在另一个类中的类;下面类B是类A的内部类。即内部类对象引用了实例化该内部对象的外围类对象。 public class A{ class B {} } 2 为什么需要内部类?(来自JAVA核心技术) 内部类方法...
  • java调用局部内部类中的方法

    千次阅读 2019-08-09 12:21:26
    局部内部类中方法的调用
  • JAVA局部内部类使用

    千次阅读 2017-04-22 00:00:11
    我是在JDK8环境下实现的,与之前的版本规则有一些变化,所以在这里mark一下 public class localInnerClass{ public static void main(String []args)... //因为是顺序编译,要在内部类后面创建实例。 } }
  • 这里到了问题的核心了,如果局部变量发生变化后,匿名内部类是不知道的(因为他只是拷贝了局不变量的值,并不是直接使用局部变量)。这里举个栗子:原先局部变量指向的是对象A,在创建匿名内部类后,匿名内部类中...
  • java局部内部类和匿名内部类

    千次阅读 2019-06-16 11:46:28
    1.局部内部类 java局部内部类就是在方法中定义的类,它仅在该方法中有效。因为它不能在该方法之外使用,因此它不能使用访问控制符和static修饰。它的应用场景是:在java代理模式中,可以直接在方法中用局部内部类...
  • 在书上看到这样一段话:如果局部内部类要访问外部类的局部变量,则此变量必须是final修饰的,否则不能访问。说是为了提高局部变量的生命周期,可不可以说的通俗一些?
  • * 标题:Java内部类[成员内部类、局部内部类、匿名内部类和静态内部类] * * 作者:Nstar * * 时间:2020年3月13日 * * 内容: * * 问:什么是内部类? * 答:在 Java 中,可以将一个类定义在另一个类里面或者一...
  • 局部内部类 1点睛 内部类不仅可以在类中定义,也可以定义在方法体或作用域内。这样的内部类作用范围仅限于方法体或特定的作用域内,因此也称为局部内部类。 2代码 class InnerClassTest { int score = 95; ...
  • 此时的局部内部类(定义在方法中的内部类)InTest中的f()访问了外部类中的局部变量x。这里x并没有用final修饰(1.8之后java隐式的将x修饰为final)如果你添加一个x=8,这里就会报错。 为什么要用final修饰 主要...
  • 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内) 3.成员内部类: 一方面,作为外部类的成员: >调用外部类的结构 >可以被static修饰 >可以被4种不同的权限...
  • 局部内部类(包含匿名内部类) 成员内部类 定义格式: 修饰符 class 外部类名称 { 修饰符 class 内部类名称 { // .... } // .... } 内部类的class文件命名为:外部类$内部类.class 使用成员内部类 间接方式:...
  • 以下关于 Java 的局部内部类的说法错误的是答:局部内部类可以访问外部类的所有成员关于赋值语句,以下选项中描述错误的是:答:设 a = 10;b = 20,执行 a,b = a,a + b print(a,b) 和 a = b b = a + b print(a,b) ...
  • 最近在看内部类的时候,有一个疑惑:局部内部类和匿名内部类只能访问final的局部变量,看了几篇博客,明白了很多,下面来分析一下:
  • java 内部类 实例内部类 局部内部类 匿名类 静态内部类 实例代码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 369,189
精华内容 147,675
关键字:

局部内部类的使用