ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

关于java内部类的一些疑问?

2022-02-23 23:33:46  阅读:218  来源: 互联网

标签:部类 java 内部 final new 疑问 public out


四大类内部类:

  1. 成员内部类
  2. 局部内部类
  3. 匿名内部类
  4. 静态内部类

1、关于final

局部、匿名内部类访问外部局部变量(方法中的变量)是否是final。

(为什么不谈成员内部类访问外部类的成员变量是否需要时final呢?因为成员内部类访问直接外部类的变量肯定都是外部类的成员变量,成员变量只要外部内的引用存在,就不会被释放。而且所有的非静态内部类都会持有外部类的引用)

结论:

基本类型:访问可以(例如:syso(xxx)),不能修改(例如:xxx=10)。

引用类型,访问和修改引用指向对象的属性可以(例如, sjq.a=10)。但是不能更改引用。(例如:在内部类对局部引用变量重新赋值,sjq=new SJQ())

 

2、关于是否持有外部类引用。

结论:三种非静态内部类都会持有外部类的引用。静态内部类不会持有外部类的引用。

为什么非静态内部类可以访问成员变量呢?因为非静态内部类隐式持有外部类的引用,也就可以访问外部类的成员变量。就算外部类显式地被释放掉,但是内部类还在,就仍会持有外部类的引用。

为什么静态内部类只能访问外部类的静态成员呢。因为静态内部类不会持有外部类的引用,而外部类的静态变量不需要创建外部类对象就可以访问。

成员内部类为什么不能定义静态成员呢?因为成员内部类依靠外部类的实例存在,假如成员内部类定义了静态成员,意味着这个静态成员可以不通过创建对象就能访问到,而成员内部类又必须通过外部内的实例才能创建,就矛盾了(这行解释只是为了方便记忆)。

现在就能搞清楚一切了,核心就是:非静态内部类隐式持有外部类的引用,静态内部类不会持有外部类的引用。

 

3、参考博客对final的解释(到位)

(1)为什么匿名内部类和局部内部类只能访问final变量:注意外部局部变量是基本数据类型和引用类型的区别。原文复制过来了:

View Code

(2)关于java方法中的局部匿名内部类调用局部变量的问题:(这篇博客说的不太对,参考《为什么匿名内部类和局部内部类只能访问final变量》的解释,是因为是引用类型)是因为局部(或者匿名)内部类访问的是外部的引用类型,修改的是引用指向对象的属性,所以可以更改。但是若在局部(或者)内部类中,修改这个引用就会报错。比如下方的代码:在内部类中sjq = new SJQ(),更改了sjq引用,会报错。

————————————————————————————————————————分割线————————————————————————————————

下面是例子:

 

 

 

 

 

package com.soecode.lyf.java;

import javax.security.sasl.SaslServer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SJQ {
    public static final int paraA=10;
    private static final String paraString="sunjignqin";
    private void myfun(Number a, String b){
        System.out.println(a+b);
        new Outer().fun1();
    }
    int a=10;

    public static void main(String[] args) {
        new SJQ().myfun(1,"2");
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        Integer[] obj = list.toArray(new Integer[5]);
        System.out.println("show obj: "+ Arrays.toString(obj));

        Object[] objects1 = list.toArray();
        Object[] objects2 = list.toArray();
        System.out.println("objects1 == objects2 : "+(objects1 == objects2));
        objects1[1]=4;
        System.out.println("show objects1: "+ Arrays.toString(objects1));
        System.out.println("show objects2: "+ Arrays.toString(objects2));
        System.out.println("show list: "+list);
        Arrays.copyOf(objects1, 2);
        System.out.println("show objects2: "+ Arrays.toString(Arrays.copyOf(objects1, 2)));
        System.out.println("show objects2: "+ Arrays.toString(Arrays.copyOfRange(objects1, 2,10)));



    }
//    class Inner1{
//        public class Inner100{
//
//        }
//    }
//    public final nimin fun(){
//        class Inner2{  // class 不能有修饰符
//
//        }
//        return new nimin(10){
//
//        };
//    }
//
//    public static  void main(String[] args) {
//        SJQ sjq = new SJQ();
//        sjq.fun();
//    }
}

class Outer {
    int out_i=1;

    Outer(){

    }
    class Inner {
        public String publicString = "Inner.publicString";
        Inner(){

        }
        int Inner_fun1(){
            return out_i;
        }
        class InnerInner{
            public String publicString = "Inner.Inner.publicString";
            int InnerInner_fun1(){
                return out_i;
            }
            class InnerInnerInner{
                public String publicString = "Inner.Inner.Inner.publicString";
                int InnerInnerInner_fun1(){
                    return out_i;
                }
            }
        }
    }
    String fun1(){
        int fun1_i=2;
        SJQ sjq = new SJQ();
        class Inner2{
            public String publicString = "Inner.publicString";
            String Inner2_fun1(){
                return out_i + publicString;
            }
            int Inner2_fun2(){
                System.out.println(fun1_i); //可以访问方法内的非final变量
//                fun1_i=2;  // 不允许对外界简单类型变量修改。1.没有定义为final类型的fun_i不能修改。2.定义为final的其它变量肯定不能改。
                sjq.a = 100;  // 可以对外界引用类型的属性进行修改。
//                sjq=new SJQ(); // 不允许对外界引用类型变量修改。
                return fun1_i + out_i ;
            }
        }
        Inner2 inner2 = new Inner2();
        String a =inner2.Inner2_fun2()+inner2.Inner2_fun1();
        return a;
    }
    static class Inner3{
        public String publicString = "Inner3.publicString";

    }

    Other anonymousOther = new Other() {
        public String publicString = "Anonymous Other.publicString";
    };
    public Other getAnonymousOther() {
        return anonymousOther;
    }

    Other Other = new Other();
    public Other getOther() {
        return Other;
    }

    public static void main(String[] args) {
        System.out.println(new Outer().new Inner());
        System.out.println(new Outer.Inner3());
        System.out.println("\t");
        System.out.println(new Outer().getAnonymousOther());
        System.out.println("\t");
        System.out.println(new Outer().fun1());

    }

}

class Other {
    public String publicString = "Other.publicString";
}
//
///**
// *  外部类的修饰符分为:可访问控制符和非访问控制符两种。
// *     可访问控制符是: 公共类修饰符 public
// *     非访问控制符有:抽象类修饰符 abstract
// *     最终类修饰符:final
// */
// class class2{
//    /**
//     * 1.成员内部类:可以有 public private protected修饰符作用在class
//     * --1.作为外部类的一个成员存在,与外部类的属性方法并列。
//     * --2.成员内部类中,不能定义静态成员(属性、方法)。
//     * --3.成员内部类中,可以访问外部类的所有成员。
//     * --4.成员内部类中,可以与外部类存在同名变量。
//     * --5.成员内部类中,访问自己的变量,使用"变量名"或者"this.变量名"。(同名变量,优先访问内部类自己的变量)
//     * --6.成员内部类中,访问外部类中与成员内部类中同名的变量,使用"外部类名字.this.变量名"。
//     * --7.成员内部类中,访问外部类中与成员内部类中不同名的变量,使用"变量名"或者"外部类名字.this.变量名"。
//     * --8.外部类的非static方法访问成员内部类的成员:a:创建内部类对象。b:调用内部类成员。
//     * --9.外部类的static方法(或者外部类的外部)访问成员内部类的成员:
//     * ----a:创建外部类对象:Out out = new Out()。
//     * ----b:通过外部类对象创建内部类对象:In in = out.new In()
//     * ----c:通过in访问内部类成员
//     * 2.局部内部类:
//     * 3.静态内部类:使用了static修饰符作用在class
//     * 4.匿名内部类:
//     * 除了内部类,
//     */
//    public class Inner{
//
//     }
//
//}
//
//abstract class  nimin{
//    public int a;
//    nimin(int a){
//        this.a = a;
//    }
//    static void fun1(){
//
//    }
//    abstract void fun2();
//}
//
///**
// * interface 接口中:方法:public abstract;属性:public、static、final
// */
//interface int1{
//    public static final int a=0;
//    public abstract void fun1();
//    public abstract void fun2();
//
//    /** 接口方法的默认修饰符包含abstract,需要被子类实现。
//    final的作用但是限制子类重新覆盖此方法,所以不能共存。*/
////    public abstract final void fun2();
//}
// class class1 implements int1{
//    @Override
//    public void fun1() {
//         new int1(){
//            @Override
//            public void fun1() {
//
//            }
//
//             @Override
//             public void fun2() {
//
//             }
//         };
//    }
//
//    @Override
//    public void fun2() {
//
//    }
//}
///**
// * abstract 修饰:类、方法
// * final 修饰:类、方法、变量
// * final 与 static可以同时用吗?
// *
// *
// */
View Code

 

标签:部类,java,内部,final,new,疑问,public,out
来源: https://www.cnblogs.com/sunupo/p/15929724.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有