Java学习的第二十九天(JavaSE最终篇_类加载机制_枚举Enum_Lambda表达式_打jar包_导jar包)

一、类加载机制

1.Java提供了一种机制把字节码文件加载进JavaJVM内存中(类的加载机制)---类加载器

1.必须将字节码文件先加载到方法区中,然后才能在堆中创建对象

2.三种类加载器

Person-->自定义类---由应用类加载器加载进内存
String、Object、Array类-->java封装好的类---由启动类加载器加载进内存
扩展类---由扩展类加载器加载进内存

2.1 应用类加载器--AppClassLoader

//想要获取类相对应的加载器--先要获取本类中的字节码对象
Class<Person> personClass = Person.class;
//获取类的加载器---getClassLoader()
ClassLoader classLoader = personClass.getClassLoader();
System.out.println(classLoader);   //应用类加载器--AppClassLoader

2.2 启动类加载器为--BootClassLoader

//启动类
Class<String> stringClass = String.class;
ClassLoader classLoader1 = stringClass.getClassLoader();
System.out.println(classLoader1);  //null
//启动类加载器不是由Java语言编写的,是由C语言编写的,所以获取不到启动类加载器的,结果为null
//要知道启动类加载器为BootClassLoader

2.3 扩展类加载器---ExtClassLoader

//扩展类---ExtClassLoader
Class<ECKeyPairGenerator> ecKeyPairGeneratorClass = ECKeyPairGenerator.class;
ClassLoader classLoader2 = ecKeyPairGeneratorClass.getClassLoader();
System.out.println(classLoader2);

3.类加载器加载字节码文件创建字节码对象的时候,类加载器对象创建几次??

Class<Person2> personClass1 = Person2.class;
ClassLoader classLoader3 = personClass1.getClassLoader();
System.out.println(classLoader==classLoader3);  //true
//同时有多个类Person和Person2,单例加载,只会使用同一个应用类加载器,两个比较返回为true

4.三个加载器是存在子父类关系的

--应用类加载器的父类是扩展类加载器
--扩展类加载器的父类是启动类加载器
ClassLoader parent = classLoader.getParent();
System.out.println(parent);//应用类加载器的父类是扩展类加载器

ClassLoader parent1 = parent.getParent();
System.out.println(parent1);//扩展类加载器的父类是启动类加载器
//三者如何进行协同工作的??通过类的双向委托机制对String和Person进行处理

5.类的双向委托机制

二、导包需要注意的细节

//导包需要注意的细节
//1.使用不同包下的类需要导包
//2.使用java封装好的类,除了lang包,其它包下的类都需要导包
com.bianyiit.cast1.Person p=new Person(); //导入com.bianyiit.cast1包
String s; //不需要导包
Scanner sc; //导入util包

三、Arrays:可以把数组转换成集合的一个工具类

String[] arr={"hello","world"};
List<String> strings= Arrays.asList(arr);//T...a可变参数,传的参数是一个数组
System.out.println(strings);

T...a可变参数拓展

//主方法调用自定义方法
/*方法名(int...a)---可变参数*/
    int sum = getSum(2, 4, 6, 3, 8, 7);
    System.out.println(sum);
    int sum1 = getSum(1, 2);
    System.out.println(sum1);

//自定义方法        
//求两个数的和getSum();
public static int getSum(int a,int b){
    return a+b;
}
//求任意个数整数的和
//T...a可变参数拓展在下面语句的参数中使用
public static int getSum(int...a){
    int sum=0;
    //a相当于是一个数组,数组名叫a,把你传过来的参数封装成一个数组
    for (int i : a) {
        sum=sum+i;
    }
    return sum;
}

四、包装类的使用

//包装类的使用---以Integer为例
int i1=123;
int i2=new Integer(1234);  //自动拆箱
Integer i3=123;  //自动装箱
int i4=new Integer("1234");
int i5=Integer.parseInt("123");//---使用频率最高的,把一个数字字符串转换成整数
String s1 = Integer.toBinaryString(1234);//将十进制转换成二进制
System.out.println(s1);
String s2 = Integer.toHexString(1234);  //将十进制转换十六进制
System.out.println(s2);
String s3 = Integer.toOctalString(1234); //十进制转八进制
System.out.println(s3);

五、枚举

--枚举的属性相当于是一个对象
--枚举是属于引用数据类型

package com.bianyiit.cast;

public class MeiJuDemo {
    public static void main(String[] args) {
        //枚举
       /*String str1 = Week.str1;
        System.out.println(str1);*/
       /* Week1 friday = Week2.Friday;
        friday.work();*/
        Week3 sunday = Week3.Sunday;
        sunday.work();
    }
}
//枚举的属性相当于是一个对象
//枚举是属于引用数据类型
enum Week3{
    Monday,Tuesday,Wednesday,Thursday,Friday,Saturday{
        @Override
        public void work() {
            System.out.println("休息");
        }
    },Sunday{
        public void work(){
            System.out.println("休息");
        }
    };

    public void work(){}
    //相当于sunday继承了Week3枚举,然后重写了枚举中的方法
}
/*用来定义星期的一个类*/
class Week2{
    /*public final static String str1="星期一";
    public final static String str2="星期二";
    public final static String str3="星期三";
    public final static String str4="星期四";
    public final static String str5="星期五";
    public final static String str6="星期六";
    public final static String str7="星期日";*/
    
    public final static Week1 Monday=new Week1(){

        @Override
        public void work() {
            System.out.println("工作");
        }
    };
    public final static Week1 Tuesday=new Week1() {
        @Override
        public void work() {
            System.out.println("工作");
        }
    };
    public final static Week1 Wednesday=new Week1() {
        @Override
        public void work() {
            System.out.println("工作");
        }
    };
    public final static Week1 Thursday=new Week1() {
        @Override
        public void work() {
            System.out.println("工作");
        }
    };
    public final static Week1 Friday=new Week1() {
        @Override
        public void work() {
            System.out.println("工作");
        }
    };
    public final static Week1 Saturday=new Week1() {
        @Override
        public void work() {
            System.out.println("休息");
        }
    };
    public final static Week1 Sunday=new Week1() {
        @Override
        public void work() {
            System.out.println("休息");
        }
    };
}
/*用来定义星期的功能*/
abstract class Week1{
    //定义星期的每一个到底是工作还是休息
    public abstract void work();
}

六、Lambda表达式

//不使用Lambda表达式之前
new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1执行了");
            }
        });
//使用Lambda表达式之后
//将匿名内部类简化成 new Thread(()->{ System.out.println("线程2执行了");System.out.println("线程2又执行了一次");});
package com.bianyiit.cast;

public class LambdaDemo {
    public static void main(String[] args) {
        //Lambda:jdk1.8提供的新特性--把一个函数(方法)当做一个参数传递
        Thread t1 = new Thread(() -> System.out.println("线程1执行了"));
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1执行了");
            }
        });
        //如果方法体里面有很多条语句需要把{}加上
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程2执行了");
                System.out.println("线程2又执行了一次");
            }
        });
        new Thread(()->{ System.out.println("线程2执行了");System.out.println("线程2又执行了一次");});

        //Lambda:jdk1.8提供的新特性--把一个函数(方法)当做一个参数传递
        work(new Lam() {
            @Override
            public void method1() {
                System.out.println("这是Lambda的演示过程1");
                System.out.println("这是Lambda的演示过程2");
            }
        });

        work(() -> {
            System.out.println("这是Lambda的演示过程3");
        });

        new LambdaTest(() -> {
            System.out.println("这是Lambda的演示过程4");
        });
    }
    public static void work(Lam l){
        l.method1();
    }
}
package com.bianyiit.cast;

//定义一个函数接口的时候必须要加上注解(里面只能放一个方法)
@FunctionalInterface
public interface Lam {
    void method1();
}
package com.bianyiit.cast;

public class LambdaTest implements Lam {
    public LambdaTest(Lam l){

    }
    @Override
    public void method1() {

    }
}

七、如何自己去打jar包给别人使用

7.1 jar包是把封装了重要内容的类进行打包的操作,别人直接拿着你的jar包就可以使用里面封装好的类中的功能
7.2 要解决的两个问题如下所示:
	//1.如何打jar包
	//2.如何往项目中引入别人打好的jar包

1.如何打jar包

步骤一:在你的项目中创建一个模块Module

步骤二:在你的Module下创建一个自定义的包

步骤三:在你的自定义包下创建一个.Java文件
Package 你的包名;
public class SumTest {
    public static void getSum(){
        System.out.println("正在求和...");
    }
}
步骤四;右击你的Module,打开你的Settings

步骤五:找到Artifacts,点击上方的“+”,选择JAR,然后选择From Moudules with dependencies

步骤六:打开之后,点击All Modules,然后找到你创建的Modules,然后点击OK

步骤七:回到这里我们可以看到Artifacts这里已经算是创建好了你的你的jar包了,在下面的output directory修改你的jar包的导出路径

步骤八:点击apply之后,点击OK,但是还没创建好jar包,继续如下操作,找到你的Build,找到Build Artifacts

在这里插入图片描述

步骤九:点击之后会弹出下面的窗口,然后点击Build,等Build结束,就可以在上面的目录中导入自定义的jar包

步骤十:在我的电脑中打开你导出jar包的位置,这个就是我们自定义的jar包啦


2.如何往项目中引入别人打好的jar包

步骤一:在你想引用的项目/Module下创建一个lib文件夹


步骤二:点击复制自定义的jar包复制粘贴至lib文件夹下

步骤三:点击复制过来的jar包,右击,点击Open Library Settings


步骤四:点击“+”号,点击Java,然后找到你的复制过来的jar包的位置,点击jar包,选择OK

步骤五:选择jar包关联的你想要应用的项目/Module,点击OK,然后继续点击apply,点击OK

步骤六:这时你的jar包已经关联至你的项目/Module下了,创建一个测试类文件测试你导入的jar包是否能够正常使用
public class Test {
    public static void main(String[] args) {
        SumTest.getSum();
    }
}


最后一步:如果进行到这步没有报错,爆红就说明导入成功,可以使用jar包内部的功能和函数了

发布了73 篇原创文章 · 获赞 11 · 访问量 2461

猜你喜欢

转载自blog.csdn.net/weixin_43908333/article/details/103339455