前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java内部类以及为什么要用public static void修饰main()函数,String args[]是什么?(浅显的一些探索)

java内部类以及为什么要用public static void修饰main()函数,String args[]是什么?(浅显的一些探索)

作者头像
兰舟千帆
发布2022-07-16 13:07:26
2360
发布2022-07-16 13:07:26
举报
文章被收录于专栏:兰舟千帆的java学习笔记

java内部类和外部类,以及main方法的一些探索

内部类

成员内部类

成员内部类就是定义在一个类的内部,其实是相当于成员变量的位置。 下面这两种其实都可以被称为成员内部类的,只不过一般static修饰的这种我们一般也可以称之为静态内部类。我们先来研究成员内部类(也可以称之为非静态内部类)怎么定义的话合理即可,明白意思就可以了。

代码语言:javascript
复制
class Outer{
	class Inner{
		//非静态成员内部类
    }
    static class Inner_1
    {
		//静态成员内部类
    }
	public static void main(String args[]){
	/*.........*/
	}

}

来看一个简单的例子,也可以自己去测试访问和定义的修饰符

代码语言:javascript
复制
package java_practice;

public class OuterandInner {
    private byte b = 1;
    static String country = "china";
    String home = "shanxi";

    public void systemdemo() {
//        System.out.println(Inner.this.name);//这样是不可以的。
    }

    public String author = "jgdabc";

    class Inner {

        String name = "jgdabc";
        //        static String name_1 = "";//这样不允许
        private String password = ".....";

        public void systemdemo() {
            System.out.println(OuterandInner.this.author);
            System.out.println(author);
            System.out.println(Inner_1.age);
//            System.out.println(name_1);//这样访问不了
            System.out.println(b);//非静态内部类可以访问到外部私有化成员
        }
    }

    static class Inner_1 {
        public static void showdemo() {
            //.....
//            System.out.println(Inner.name);//这样不可以
//            Inner inner = new Inner();//不可以这样去new,因为没有main方法
//            System.out.println(b);//静态局部内部类是不能访问到外部类私有成员的
            System.out.println(country);

        }

        String name_1 = "jgdabc_1";
        private String password_1 = "lmddkskk";
        static int age = 19;

        public void systemdemo() {
//            System.out.println(OuterandInner.this.author);//这样是不可以的
            System.out.println(OuterandInner.country);//这样可以访问,并且直接通过类名进行访问

        }

    }

    public static void main(String args[]) {
        System.out.println("......");

        OuterandInner outerandInner = new OuterandInner();
//        System.out.println(outerandInner.name);//访问不到内部类成员
//        System.out.println(name);//
        System.out.println(outerandInner.author);//自己的成员变量直接可以通过实例访问
        Inner inner = outerandInner.new Inner();

        System.out.println(inner.name + inner.password);
//        Inner inner1 = new Inner();//动态的外部类不能被直接在外部类new()
//        System.out.println(name_1);//不能访问
        OuterandInner outerandInner1 = new OuterandInner();
//        System.out.println(outerandInner1.name);//不能访问
        Inner_1 inner_1 = new Inner_1();//静态的可以直接进行new实例化
        System.out.println(inner_1.name_1 + inner_1.password_1);
        System.out.println(Inner_1.age);//直接通过类名来调用静态成员内部类的静态成员
//        System.out.println(Inner_1.name);//这样是不可以的
        Inner_1.showdemo();//也可以直接通过类名调用静态成员内部类的静态方法。


    }
}

上面代码测试了一些常规的方法。下面简单说明几点

1:首先非静态成员内部类里面是不可以定义静态的属性的,否则编译不会通过。

2:非静态成员内部类成员不能被外部直接访问,不能只通过实例外部类访问内部类成员

3:访问非静态成员内部类成员属性可以通过外部类实例的对象.new 内部类, 示例如下

代码语言:javascript
复制
// An highlighted block
        Inner inner = outerandInner.new Inner();

4:非静态成员内部类可以访问到外部类的属性 然后可以通过inner调用非静态成员内部类属性。

5:非静态成员内部类可以访问到外部私有化属性。


6:外部类也是不能直接访问静态局部成员内部类成员的,这个特点同属于对内部类访问的特点。 7:静态成员内部类可以直接自己进行实例化,而无需通过外部类实例进行调用实例化。 8:静态成员内部类不可以访问到外部类的私有化成员

9:静态成员内部类可以直接访问到外部类的静态成员

10:静态成员内部类不能直接访问外部类非静态成员

局部内部类

局部内部类是一个在方法中定义的内部类 既然是局部内部类,定义在方法体中,那么只在当前方法体当中有效。无论是静态的还是非静态的,都是一样的法则。

特别注意它的作用范围,就是是去实例化它所在的类,只要不再方法体内都是无效。

代码语言:javascript
复制
public void systemdemo() {
        class demo_test {
            int age = 19;
            public int id = 123;
//          static String name= "hello";//不可以有静态修饰的成员
//            static void system_demo()
//            {
//                //不可以这样用
//            }
            private String password = "";
            public void show_demo() {
                System.out.println("我是局部内部类");
                   System.out.println(home+b+password);//可以访问到外部类的成员,即便是私有的。
            }
        }
        demo_test demo_test = new demo_test();
        demo_test.show_demo();
//        System.out.println(Inner.this.name);//这样是不可以的。
    }
//    new demo_test();//这样是不可以的

没有静态局部内部类一说

在这里插入图片描述
在这里插入图片描述

匿名内部类

匿名内部类也是经常会用到,就比如在重写一个比较器的时候可以通过类名内部类实现。另外,我们也可以自己定义一些具备功能的接口去实现匿名内部类。 简单举例说明一下

代码语言:javascript
复制
package java_practice;
class demo{
    public void demo()
    {
        System.out.println("demo");
    }
}

public class AnonymousInner {
    public static void main(String args[])
    {
        new demo(){
            public void demo()
            {
                System.out.println("demo重写");
            }
        }.demo();

    }

}
在这里插入图片描述
在这里插入图片描述

下面这个例子实现了内名进行重写比较器

代码语言:javascript
复制
package java_practice;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo01 {
    public static void main(String args[])
    {
        TreeMap tm = new TreeMap<String,String>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                //。。。
            }
        });
        tm.put("Hello","world");
        String  set = String.valueOf(tm.keySet());
        System.out.println(set);
        System.out.println(set.getClass());
        System.out.println(set);

    }
}

代码语言:javascript
复制
package java_practice;

public class Student implements Comparable<Student>{
    private int age;
    private String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }





    @Override
    public int compareTo(Student s) {
        int num = this.age - s.age;
        int num2 = num == 0 ? this.name.compareTo(s.name) : num;
        return num2;
    }
}
代码语言:javascript
复制
package java_practice;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo1 {
    public static void main(String args[]) {
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num = s1.getAge() - s2.getAge();
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return num2;
            }
        });

        Student s1 = new Student(29, "西施");
        Student s2 = new Student(28, "王昭君");
        Student s3 = new Student(30, "貂蝉");
        Student s4 = new Student(33, "杨玉环");
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        for (Student s : ts) {
            System.out.println(s.getName() + "" + s.getAge());
        }

    }
}

匿名内部类实现接口

先给一个不适用匿名内部类实现的例子

代码语言:javascript
复制
package java_practice;
interface Demo_{
    void demo_d();
}
class Demo_im implements Demo_
{

    @Override
    public void demo_d() {
        System.out.println("实现demo_");
    }
}
public class Demo_de {

    public static void main(String args[])
    {
        Demo_im demo_im = new Demo_im();
        demo_im.demo_d();


    }
}
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
package java_practice;
interface Demo_{
    void demo_d();
}

public class Demo_de {

    public static void main(String args[])
    {
        Demo_ demo= new Demo_(){

            @Override
            public void demo_d() {
                System.out.println("匿名实现接口");
            }
        };
        demo.demo_d();
    }
}
在这里插入图片描述
在这里插入图片描述

main方法的一些疑问

为什么main方法要用static修饰

我就疑惑为什么mian方法非要是静态的? 我的理解比较浅显。因为这样的设计一定经过很好的预先思考的。对java的底层理解不是很深入。所以自己去参考了一些说法。

首先我们自己从程序执行上面去理解。我们的main方法是在类中,在类中的方法的一个特点就是如果如果不用static修饰,那就必须用实例化才可以访问,但是main是作为程序的如果啊!我们如果不进行直接访问的话,就得自己去实例化main,这样就比较复杂了。所以用static修饰得话,对我们得使用带来了一定得不变。这样其实这样修饰类成为了一种约定。

static修饰方法得特点再说明一下。

在这里插入图片描述
在这里插入图片描述

也就是说,static 修饰的方法陈为静态方法,静态方法是不依赖类的实列的,不需要通过类的实例去调用。main方法的调用是通过类的加载,链接,以及初始化,main没有被实例化过,所以需要调用的只能是通过声明为静态,然后进行调用。

为什么需要public 修饰符?

这个就比较简单了。我们的java程序需要靠java虚拟机来调用,我们的这种执行调用方式属于外部调用,如果没有public修饰,是无法实现调用的,程序也就无法执行。

为什么需要void修饰?

还是从程序执行需要方面来看,如果没有void修饰是一定需要返回值的。返回值对main又有什么意义呢?我们程序从main函数进行输出就是为了输出程序执行的内容。没有必要去返回值,返回又给谁呢?这不是我们需要的。

对比c,c++,的话,我们就好奇,为什么c,c++就可以进行返回,int main(),执行机制不一样啊,c,c++在程序进入函数执行的是偶,会启动运行时库,然后初始化环境,启动入口函数,然后程序进行执行,执行完毕后,退回运行时库,退回操作系统,然后操作系统继续调度其它的程序。

==但是java就不一样了。我们的java是由jvm进行调度的,jvm调度main函数,jvm被设计为不接受任何返回值,所以也就不能进行返回。 自己的理解浅显,希望自己可以不断学习,获得更多更加深入的认识。

为什么main方法里面的参数是(String[] args)(一个字符串数组?)

String[] args[]或者String args[] 这样都是没有问题的,这个字符串主要的作用就是运行main函数的输入参数,不然它也不会写在那里,我们给main传入参数,args这个数组就会进行接收。

具体是如何传入呢? 可以利用idea来进行很方便的传参,

在这里插入图片描述
在这里插入图片描述

主函数里面对参数进行遍历

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

但是其实不知道这样进行传参的具体意义所在。

自己的理解浅显,希望自己可以不断学习,获得更多更加深入的认识。 希望得到指点。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • java内部类和外部类,以及main方法的一些探索
  • 内部类
    • 成员内部类
      • 局部内部类
        • 匿名内部类
        • main方法的一些疑问
          • 为什么main方法要用static修饰
            • 为什么需要public 修饰符?
              • 为什么需要void修饰?
                • 为什么main方法里面的参数是(String[] args)(一个字符串数组?)
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档