Java 字符串常量池 +反射,枚举和lambda表达式

文章目录

字符串常量池

  1. 用来存储是一个固定大小的HashTable
  2. 常量池在堆当中
java 复制代码
public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        String s4 = new String("hello");

        System.out.println(s1 == s2);// true
        System.out.println(s1 == s3);// false
        System.out.println(s3 == s4);// false
    }
  1. 每次用双引号的时候都会去常量池中检查一遍是否存在字符串
  2. 如果常量池中有这个字符串,就不会生成直接引用,没有就会新建一个字符串
  3. 双引号引起的才会放入到常量池当中


java 复制代码
public static void main(String[] args) {
        char[] ch = new char[]{'a','b','c'};
        String s1 = new String(ch);
        // s1.intern();
        // 让s1所指的对象入池,如果在常量池中存在就不入池
        String s2 = "abc";
        System.out.println(s1 == s2);// false 有s1.intern()就是true
    }


反射

  1. 反射:在运行 状态中,对于任何一个类,都能够知道这个类的所有属性和方法

反射实例

获取class对象的三种方式

  1. 使用 Class.forName("类的全路径名"); 静态方法。
    前提:已明确类的全路径名。
  2. 使用 .class 方法。
    说明:仅适合在编译前就已经明确要操作的 Class
  3. 第三种,使用类对象的 getClass() 方法
java 复制代码
public static void main(String[] args) {
        Class<?> c1 = null;
        try {
            c1 = Class.forName("Demo1.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Class<?> c2 = Student.class;

        Student student = new Student();
        Class<?> c3 = student.getClass();

        // Class 对象只有一个
        System.out.println(c1 == c2);// true
        System.out.println(c2 == c3);// true
    }

反射的使用实例

java 复制代码
package Demo1;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectClassDemo {
    // 在类外进行反射,获取Student对象中的私有成员和方法
    public static void reflectNewInstance(){
        // 创建一个Class对象
        Class<?> classStudent = null;
        try {
            classStudent = Class.forName("Demo1.Student");
            // 得到Class类的实例
            // 获取类的实例擦成了Object类,向下转型
            Student student = (Student)classStudent.newInstance();
            System.out.println(student);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 反射私有的构造方法
    public static void reflectPrivateConstructor(){
        Class<?> classStudent = null;
        try {
            classStudent = Class.forName("Demo1.Student");
            // 获取构造方法
            Constructor<?> constructor = classStudent.getDeclaredConstructor(String.class,int.class);
            // 如果是私有的构造方法确定要修改,要设置为true
            constructor.setAccessible(true);
            // 利用构造方法构造对象
            Student student = (Student)constructor.newInstance("xiaoming",15);
            System.out.println(student);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 获取私有字段
    public static void reflectPrivateField(){
        Class<?> classStudent = null;
        try {
            classStudent = Class.forName("Demo1.Student");
            // 获取字段
            Field filed = classStudent.getDeclaredField("name");
            filed.setAccessible(true);
            // 获取对象
            Student student = (Student)classStudent.newInstance();
            // 修改该对象的字段
            filed.set(student,"caocao");
            System.out.println(student);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 获取私有的方法
    public static void reflectPrivateMethod(){
        Class<?> classStudent = null;
        try {
            classStudent = Class.forName("Demo1.Student");
            // 获取私有的方法对象
            Method method = classStudent.getDeclaredMethod("function",String.class);
            // 设置为true可以调用私有方法
            method.setAccessible(true);
            // 获取student对象
            Student student = (Student) classStudent.newInstance();
            // 调用私有的方法
            method.invoke(student,"我是一个反射的参数");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
    public static void main(String[] args) {
        // reflectNewInstance();
        // reflectPrivateConstructor();
        // reflectPrivateField();
        reflectPrivateMethod();
    }
}

枚举

使用在switch语句中

java 复制代码
public enum TestEnum {
    RED,GREEN,BLACK;
// 使用在switch语句
    public static void main1(String[] args) {
        TestEnum color = RED;
        switch (color){
            case GREEN:
                System.out.println("GREEN");
                break;
            case RED:
                System.out.println("RED");
                break;
            case BLACK:
                System.out.println("BLACK");
                break;
            default:
                System.out.println("error");
                break;
        }
    }
}

枚举函数的使用

  1. values() 方法是编译器生成的
  2. values() 方法是枚举类型的隐式方法
    在 Java 中,所有枚举类型(enum)都会自动生成一个 values() 静态方法,它返回该枚举的所有实例(常量)组成的数组。
java 复制代码
public enum TestEnum {
    RED,GREEN,BLACK;

    public static void main(String[] args) {
        // 以数组形式返回枚举类型的所有成员
        TestEnum[] testEnums = TestEnum.values();
        for(int i = 0;i < testEnums.length;i++){
            // 获取枚举成员的索引位置
            System.out.println(testEnums[i].ordinal());
        }
        System.out.println("===");
        // 将普通字符串转化为枚举实例
        TestEnum v = TestEnum.valueOf("BLACK");
        System.out.println(v);
        System.out.println("===");
        // 比较他们在定义时的顺序
        System.out.println(RED.compareTo(BLACK));// -2
    }
}
  1. 枚举的构造方法默认是私有的
java 复制代码
public enum TestEnum {
    RED(1,"红色"),
    GREEN(2,"绿色"),
    BLACK(3,"蓝色");

    public int ordinal;
    public String color;

    private TestEnum(int ordinal,String color){
        this.ordinal = ordinal;
        this.color = color;
    }
}
  1. 枚举不能被继承,因为它的构造方法是私有的,要被继承需要重写父类的构造方法
  1. 枚举对象非常安全,就算通过反射也不能创建一个枚举对象的
  1. 枚举不能通过反射直接实例化不能通过反射调用枚举的构造方法

枚举的构造方法默认是 private,即使你不写 private,编译器也会自动加上。

枚举的实例必须在枚举内部显式定义

java 复制代码
package Demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectClassTestEnum {
    public static void main(String[] args) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException, NoSuchMethodException,
            InvocationTargetException {
        // 获取Class类
        Class<?> classTestEnum = Class.forName("Demo2.TestEnum");
        // 获取枚举类的对象
        Constructor<?> constructor = classTestEnum.getDeclaredConstructor
                (String.class,int.class,int.class, String.class);
        constructor.setAccessible(true);

        TestEnum testEnum = (TestEnum) constructor.newInstance("黑色",2,1,"白色");
        System.out.println(testEnum);
    }
}

Lambda表达式

  1. 函数式接口:一个接口只有一个抽象方法

实例

java 复制代码
package Demo3;

import java.util.Comparator;
import java.util.Map;
import java.util.PriorityQueue;

//无返回值无参数
// @FunctionalInterface表明着是一个函数式接口
@FunctionalInterface
interface NoparameterNoReturn{
    // 只能有一个抽象方法
    void test();
}

//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
void test(int a);
}

//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
void test(int a,int b);
}

//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {
int test();
}

//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
}

//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
int test(int a,int b);
}

public class Test {
    public static void main(String[] args) {
        // 有返回值
        // 无参数
        // NoParameterReturn noParameterReturn = ()->{return 10;};
        NoParameterReturn noParameterReturn = ()->10;
        System.out.println(noParameterReturn.test());

        // 一个参数
        // OneParameterReturn oneParameterReturn = (a)->{return a;};
         OneParameterReturn oneParameterReturn = a-> 20;
        System.out.println(oneParameterReturn.test(10));

        // 两个参数
        MoreParameterReturn moreParameterReturn = (int a,int b)->{return a + b;};
        System.out.println(moreParameterReturn.test(10,20));
    }

    public static void main2(String[] args) {
        // lambda表达式 无参数
        // 无返回值
        NoparameterNoReturn noparameterNoReturn = ()-> System.out.println("重写了test1()方法");
        noparameterNoReturn.test();

        // 1个参数
        OneParameterNoReturn oneParameterNoReturn = (a)->{
            System.out.println("oneParameterNoReturn " + a);
        };
        oneParameterNoReturn.test(10);

        /*
        OneParameterNoReturn oneParameterNoReturn = a->
        System.out.println("oneParameterNoReturn " + a);
         */
        //                                             可以省略类型
        MoreParameterNoReturn moreParameterNoReturn = (int a,int b)->{
            System.out.println(a+b);
        };
        moreParameterNoReturn.test(1,2);
    }
    public static void main1(String[] args) {
        // 匿名内部类
        NoparameterNoReturn noparameterNoReturn = new NoparameterNoReturn() {
            @Override
            public void test() {
                System.out.println("重写了test1()方法");
            }
        };

        noparameterNoReturn.test();

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

        PriorityQueue<Integer> priorityQueue1 = new PriorityQueue<>((o1,o2)->{return o1 - o2;});
    }
}

变量捕获

  1. 变量捕获:要么是常量,要么是没有被修改过的变量

匿名内部类

lambda表达式

lambda表达式在集合当中的使用

  1. 打印,ArrayList的forEach方法
java 复制代码
public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        list.add("queue");

        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        list.forEach(s-> System.out.println(s));
    }
  1. sort方法
java 复制代码
/*list.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });*/
        list.sort((o1,o2)->o1.compareTo(o2));

        list.forEach(s-> System.out.println(s));
  1. map方法
java 复制代码
public static void main(String[] args) {
        HashMap<Integer,String> hashMap = new HashMap<>();
        hashMap.put(1,"a");
        hashMap.put(2,"b");
        hashMap.put(3,"c");

        /*hashMap.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer integer, String s) {
                System.out.println("Integer:"+ integer + " String:" + s);
            }
        });*/

        hashMap.forEach((a,b)-> System.out.println("Integer:"+ a + " String:" + b));
    }
  1. lambda表达式可读性比较差,不可调试,但是比较简洁
相关推荐
ATaylorSu几秒前
经典算法之美:冒泡排序的优雅实现
开发语言·笔记·学习·算法
雨白1 小时前
开发 SunnyWeather:Android 天气预报 App(下)
android
唐叔在学习1 小时前
Maven - 并行安全无重复打包构建原理揭秘
java·maven·maven并行构建·maven反应堆原理
FlechazoCLF1 小时前
QT中使用OpenCV保姆级教程
开发语言·qt·opencv
山间小僧1 小时前
「查漏补缺」ZGC相关内容整理
java·jvm·后端
bluebonnet271 小时前
【python】转移本地安装的python包
java·python·eureka
lifallen1 小时前
AbstractExecutorService:Java并发核心模板解析
java·开发语言·数据结构·算法
weixin_437499922 小时前
【PHP 构造函数与析构函数:从基础到高级的完整指南】
开发语言·php
Mu.3872 小时前
加密与安全
java·开发语言
DKPT2 小时前
Java设计模式之行为型模式(解释器模式)实现方式详解
java·笔记·学习·设计模式·解释器模式