Home  >  Article  >  Java  >  Java internal class example analysis

Java internal class example analysis

WBOY
WBOYforward
2023-04-23 14:43:14531browse

    1. Concept and classification of internal classes

    If a class is defined inside another class or inside an interface or inside a method body, this class will be It is called an inner class. We might as well call the class where the inner class is located a peripheral class. In addition to the inner classes defined in classes, interfaces, and methods, there is also a special inner class, which is to use the keyword new to create an anonymous class. Object, and this anonymous class is actually an inner class, specifically an anonymous inner class, which is often used to construct objects by passing in constructor arguments, such as the creation of PriorityQueue objects.

    When a class is defined inside another class or inside an interface, and there is no static modification, the internal class is called an instance internal class. When static modification is used, the internal class is called a static internal class ( Nested class), define a class inside the code block, especially inside the method body. This internal class is called a local internal class or a local internal class, and the other is the anonymous internal class mentioned above.

    2. Instance inner class

    2.1 Creation of instance inner class

    The definition of instance inner class is very simple, just define it directly inside the outer class. The question is how to create an inner class object. First of all, you need to understand that the member variables and methods in the inner class and the outer class are on an equal footing. They all belong to the outer class object (without static modification), so if you want the inner class object, you must first have Peripheral class object, the first way to create an inner class object is to use a method to return an inner class object, and the type of this inner class object is OutClassName.InnerClassName, that is, outer class name.inner class name.

    public class Outer {
    
        class Inner1 {
            private String str;
            public Inner1(String s) {
                this.str = s;
            }
            public String readStr() {
                return this.str;
            }
        }
    
        class Inner2 {
            private int val;
            public Inner2(int i) {
                this.val = i;
            }
            public int readVal() {
                return this.val;
            }
        }
        //创建内部类
        public Inner1 creatInner1(String s) {
            return new Inner1(s);
        }
        public Inner2 creatInner2(int i) {
            return new Inner2(i);
        }
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner1 inner1 =  outer.creatInner1("Inner1");
            Outer.Inner2 inner2 = outer.creatInner2(2);
    
            System.out.println(inner1.readStr());
            System.out.println(inner2.readVal());
        }
    }
    //output:
    Inner1
    2
    
    Process finished with exit code 0

    2.2 Use .this and .new

    Of course, there are other ways to create an inner class, which is to use the object of the outer class .new to create an inner class object. The syntax is:

    External class object.new internal class construction method;

    public class Outer {
    
        class Inner1 {
            private String str;
            public Inner1(String s) {
                this.str = s;
            }
            public String readStr() {
                return this.str;
            }
        }
    
        class Inner2 {
            private int val;
            public Inner2(int i) {
                this.val = i;
            }
            public int readVal() {
                return this.val;
            }
        }
    
    
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner1 inner1 =  outer.new Inner1("Inner1");
            Outer.Inner2 inner2 = outer.new Inner2(2);
    
            System.out.println(inner1.readStr());
            System.out.println(inner2.readVal());
        }
    }
    //output:
    Inner1
    2
    
    Process finished with exit code 0

    The characteristics of internal classes are more than that. Internal classes can also be linked to peripheral classes. First, instantiate the internal class object The creation relies on the reference of the outer class object. The member variables of the instance inner class and the outer class have the same status. If you want to access the member variables and methods of the outer class (especially variables with the same name) through the inner class object. In the inner class, you can use the outer class name.this to obtain the outer class object, and then use the obtained outer class object to use the variables and methods of the outer class.

    public class Outer {
        private String outStr;
        public Outer(String str) {
            this.outStr = str;
        }
    
        public void printOuter() {
            System.out.println(this.outStr);
        }
    
        class Inner {
            private String str;
            public Inner(String s) {
                this.str = s;
            }
            public String readStr() {
                return this.str;
            }
            //使用.this获取父类对象引用
            public Outer outer() {
                return Outer.this;
            }
        }
    
    
    
        public static void main(String[] args) {
            Outer outer = new Outer("outerString");
            Outer.Inner inner = outer.new Inner("innerString");
    
            Outer out = inner.outer();
            out.printOuter();
        }
    }
    //output:
    outerString
    
    Process finished with exit code 0

    In fact, there are two thiss in the inner class object. Directly using the this. member obtains the members of the inner class object itself, while using the outer class name.this. member like above obtains the members of the outer class. , that is to say, in the inner class, this points to the reference of the inner class object itself, and the outer class name.this points to the reference of the outer class object.

    When the inner class and outer class variable names have the same name, these two this are of great use.

    public class Outer {
        public int a = 12;
        public int b = 16;
        public int c = 20;
    
        class Inner{
            public int a = 8;
            public int c = 48;
            public int d = 2;
    
            public void printVal() {
                System.out.println("外围类变量a=" + Outer.this.a);
                System.out.println("外围类变量b=" + Outer.this.b);
                System.out.println("外围类变量c=" + Outer.this.c);
                System.out.println("内部类变量a=" + this.a);
                System.out.println("内部类变量c=" + this.c);
                System.out.println("内部类变量d=" + this.d);
            }
        }
    
        public Inner creatInner() {
            return new Inner();
        }
    
        public static void main(String[] args) {
            Outer outer = new Outer();
    
            Outer.Inner inner = outer.creatInner();
            inner.printVal();
        }
    }
    //output:
    外围类变量a=12
    外围类变量b=16
    外围类变量c=20
    内部类变量a=8
    内部类变量c=48
    内部类变量d=2
    
    Process finished with exit code 0

    If the same name does not appear, just obtain the member directly. You do not need to use this as mentioned above. If the same name appears, the directly accessed member defaults to the internal class object.

    2.3 Inner class implements iterative printing

    The inner class can have access to all elements of the outer class, so we can try to use the inner class to traverse and output the elements in the outer class, although the inner class The status of members of the outer class is equal, but the inner class is also a class after all. It can also inherit classes and implement interfaces like the outer class.

    import java.util.Arrays;
    
    interface Selector{
        //判断是否迭代完全部元素
        public boolean end();
        //获取当前元素
        public Object current();
        //迭代下一个元素
        public void next();
    }
    
    public class SequeArray {
        private Object[] items;
        private int usedSize;
    
        public SequeArray(int capacity) {
            items = new Object[capacity];
        }
        public void add(Object val) {
            if (usedSize == items.length) items = Arrays.copyOf(items, 2 * usedSize);
    
            items[usedSize++] = val;
        }
    
        private class SequeSelector implements Selector{
            private int index;
    
            public boolean end() {
                return index == usedSize;
            }
            public Object current() {
                return items[index];
            }
            public void next() {
                if (index < usedSize) index++;
            }
        }
        public SequeSelector sequeSelector() {
            return new SequeSelector();
        }
    
        public static void main(String[] args) {
            SequeArray array = new SequeArray(10);
    
            for (int i = 0; i < 10; i++) {
                array.add(i+1);
            }
            //发生了向上转型
            Selector selector = array.sequeSelector();
    
            while (!selector.end()) {
                System.out.print(selector.current() + "   ");
                selector.next();
            }
        }
    }
    //output:
    1   2   3   4   5   6   7   8   9   10   
    Process finished with exit code 0

    2.4 Inheritance of inner classes

    Inheritance of inner classes is a bit troublesome, because the constructor of the inner class must rely on the reference of the outer class, so a special syntax is needed to explain the relationship between the inner class and Association of peripheral classes:

    Peripheral class reference.super();

    For specific how to use it, see the following code:

    public class Outer {
        class Inner{
            
        }
    }
    class Person extends Outer.Inner {
        private String str;
        private int id;
        public Person(Outer out, String str, int id) {
            out.super();
            this.str = str;
            this.id = id;
        }
        public void readVal() {
            System.out.println(this.str + this.id);
            
        }
    }

    When the inner class is When inheriting, you need to pass the reference of the peripheral class into the constructor of the parent class and call super() to pass the compilation.

    If the inner class inherits the outer class, just inherit it directly, no need to bother.

    When the program generates a bytecode file of a java file, name it as public external class $ internal class.

    Inner classes can be nested infinitely, but generally no one does this.

    3. Static inner class

    Static inner class is also called nested class. It is to add a static keyword before the definition of the instance inner class, like the following:

    public class Outer {
        
        static class Inner{
            
        }
    }

    The difference from instance inner classes is that static inner classes belong to classes rather than objects, so the creation of static inner classes does not depend on external class objects. This is one of the biggest differences from instance inner classes.

    public class Outer {
        static class Inner{
            private String str;
            public Inner(String s) {
                str = s;
            }
        }
    
        public static void main(String[] args) {
            Outer.Inner inner = new Outer.Inner("我是静态内部类!");
            System.out.println(inner.str);
        }
    }
    //output:
    我是静态内部类!
    
    Process finished with exit code 0

    4. Anonymous inner classes

    We have already seen the usage of anonymous inner classes, that is, when creating a PriorityQueue object, a small heap is created by default, and a comparator needs to be passed in to create a large heap. heap.

            PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
            });

    Like the above method, use the new keyword to create an object of an anonymous class as an actual parameter. The anonymous class inside is an anonymous inner class. The Comparator anonymous class object in the creation process is the one passed by inheritance. Parameter type, here is the Comparator class.

    If you use a custom type to pass into the priority queue, you must implement a comparator. The most common way to implement a comparator is anonymous inner classes and Lambda expressions.

    假设我有一个Person类数组,需要对他们的name排序,如果不使用内部类,就需要在Person类中实现比较器。

    import java.util.Arrays;
    import java.util.Comparator;
    
    class Preson {
        public String name;
        public Integer id;
        public Preson(String name, Integer id) {
            this.name = name;
            this.id = id;
        }
    
        @Override
        public String toString() {
            return "Preson{" +
                    "name=&#39;" + name + &#39;\&#39;&#39; +
                    ", id=" + id +
                    &#39;}&#39;;
        }
    }
    class PersonComparator implements Comparator<Preson> {
        @Override
        public int compare(Preson o1, Preson o2) {
            return o1.name.compareTo(o2.name);
        }
    }
    public class Main {
        public static void main(String[] args) {
            Preson preson1 = new Preson("aboluo", 24);
            Preson preson2 = new Preson("zhousi", 25);
            Preson preson3 = new Preson("syyfjy", 2);
            Preson[] presons = {preson1, preson2, preson3};
            Arrays.parallelSort(presons, new PersonComparator());
            System.out.println(Arrays.toString(presons));
        }
    }
    //output:
    [Preson{name=&#39;aboluo&#39;, id=24}, Preson{name=&#39;syyfjy&#39;, id=2}, Preson{name=&#39;zhousi&#39;, id=25}]
    
    Process finished with exit code 0

    使用内部类上述代码就变为:

    import java.util.Arrays;
    import java.util.Comparator;
    
    class Preson {
        public String name;
        public Integer id;
        public Preson(String name, Integer id) {
            this.name = name;
            this.id = id;
        }
    
    
        @Override
        public String toString() {
            return "Preson{" +
                    "name=&#39;" + name + &#39;\&#39;&#39; +
                    ", id=" + id +
                    &#39;}&#39;;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Preson preson1 = new Preson("aboluo", 24);
            Preson preson2 = new Preson("zhousi", 25);
            Preson preson3 = new Preson("syyfjy", 2);
            Preson[] presons = {preson1, preson2, preson3};
            Arrays.parallelSort(presons, new Comparator<Preson>() {
                @Override
                public int compare(Preson o1, Preson o2) {
                    return o1.name.compareTo(o2.name);
                }
            });
            System.out.println(Arrays.toString(presons));
        }
    }
    //output:
    [Preson{name=&#39;aboluo&#39;, id=24}, Preson{name=&#39;syyfjy&#39;, id=2}, Preson{name=&#39;zhousi&#39;, id=25}]
    
    Process finished with exit code 0

    还有一个本地内部类,就是类定义在方法中,就不多说了,基本上不用,用法如下:

    public class Outer {
        public void func() {
            class Inner{
                //
            }
        }
    }

    The above is the detailed content of Java internal class example analysis. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete