首页 > 编程语言 >On_Java_Advanced_Edition

On_Java_Advanced_Edition

时间:2022-09-27 07:33:20浏览次数:46  
标签:case Java String System Edition println public Advanced out

01 枚举类型

1.2 在枚举类型中添加自定义方法

package org.example;

public enum Run_RR {
    YANG("This is most helpful.."),
    QIAN("This is a good test of Enum"),
    TAO("This is a best chance for help poor boys..");

    private String description;

    private Run_RR(String description) {
        this.description = description;
    }

    public String getDescription(){
        return description;
    }
}

这么说,里面的YANG QIAN TAO这种类型其实也就是Run_RR的实例被,很像是一种递归调用的感觉。

重载枚举类型中的方法

package org.example.enums;

import java.util.stream.Stream;

public enum SpaceShip {
    SCOUT, CARGO, TRANSPORT, CRUISER, BATTLESHIP, MOTHERSHIP;

    @Override
    public String toString() {
        String id = name();
        String lower = id.substring(1).toLowerCase();
        return id.charAt(0) + lower;
    }

    public static void main(String[] args) {
        Stream.of(values())
                .forEach(System.out::println);
    }
}

Enum 在编译器内部的类型就类似于这样

enum Spring{
    TAO,
    THIN;
}

和这个 Enum<Spring> 是一样的。

也可以用接口组织枚举。

package MyTools;

import java.util.Arrays;

public class ConstantsEnum {
    public static void main(String[] args) {
        for (var x :
                Constance.CLASSPATH.info().split(";")) {
            System.out.println(x);
        }
    }
}

enum Constance {
    CLASSPATH {
        @Override
        String info() {
            return System.getenv("PATH");
        }
    };

    abstract String info();
}

枚举类型也可以实现方法,不仅限于abstract,也可以用普通的重写方法。你差不多可以把它当作一个内部类使用。

当然,也可以拥有多个构造器

enum Test{
    
    Tess("Look"),
    Tesss(12);
    
    int value;
    String s;
    
    Test(int value){
        this.value = value;
    }
    
    Test(String s){
        this.s = s;
    }
}

JDK17后,switch(){}语句的诞生使得枚举的作用变得越来越多

public class Test {

    public static void main(String[] args) {
        test(new Tye());
    }

    static void test(Try tr) {
        switch (tr) {
            case TT c -> {
                System.out.println("This is TT.c");
            }
            case Tye s -> {
                System.out.println("This is Tye.s");
            }
        }
    }
}

sealed interface Try {
    void show();
}

final class Tye implements Try {
    @Override
    public void show() {
        System.out.println(getClass().getSimpleName());
    }
}

final class TT implements Try {
    @Override
    public void show() {
        System.out.println(getClass().getSimpleName());
    }
}

1.8 用EnumSet来代替标识

性能是他的设计目标之一。其内部实现其实是一个long数组。

EnumSet<Enum> point = Enum.noneOf(Enum.class)

EnumSet<Enum> point = Enum.Of(多个参数都可以,有三到五个的版本,也有变形参数的版本)

这体现了他对于性能的关注。

1.9 使用EnumMap

这是一种特殊的Map,他要求自身的所有键来自于某个枚举类型。由于枚举的约束,EnumMap的内部可以作为一个数组来实现。

因此他们的性能非常好,你可以放心的使用EnumMap来实现基于枚举的查询。

你只能用·枚举·中的元素作为键来调用put()方法。除此之外,就和调用一个普通的Map没什么区别了。

Switch需要注意的地方(自己总结的)

  1. switch支持了箭头语法,JDK14增加了swtich的能力。在箭头语法中,不需要break来断句了。

  2. 箭头语法可以直接成为返回值
    switch(value){ case Test t -> "This is a output.." }
    用print直接就可以把switch输出。

  3. JDK17增加了预览功能,注意是预览功能,现在还是不能用的。
    就是可以在case中使用null这个选项了。

  4. JDK14中也可以把swtich的普通模式(就是使用case 1: System.out.println();break;这种)转变为可以返回值的switch语句
    具体的关键字是yield。

    var i = switch(s){
        case 1 : yield 1;
        case 2 : yield 2;
        case 3 : yield 3;
        default : yield "default";
    }
    System.out.print(i);
    
    var result = switch(s){
        case "i" -> 1;
        case "o" -> 2;
        case "p" -> 3;
        default -> 0;
    }
    
  5. JDK16最终完成了JEP的定稿,下面是新旧两者方法的区别;

    public class Test_2 {
        
        static void dumb(Object x){
            if (x instanceof String){
                String x1 = (String) x;
                System.out.println(x1);
            }
        }
        
        static void smart(Object x){
            if (x instanceof String s && s.length() > 0)
                System.out.println(s);
        }
        
    }
    

    这里面的s被称为 == 模式变量 ==。(但是它有一个极端情况,就是在这个if语句外面也有可能会捕捉到他。虽然这不是一个bug但是最好不要使用)

1.17 新特性:模式匹配

1.17.2 守卫设计模式

用的就是类似于这种语法

static void classify(Shape s) {
    System.out.println(switch (s) {
        case Circle c && c.area() < 100.0 -> "Small Circle" + c;
        case Circle c -> "Large Circle: " + c;
        case Rectangle r && r.side1() == r.side2() -> "Square: " + r;
        case Rectangle r -> "Rectangle: " + r;
    });
}

1.17.3 支配性

switch中的顺序很重要,如果基类先出现,就会支配任何出现在后面的case

就像异常那样,Exception如果放在最前面,那么后面的异常就不会再有机会被捕获。

1.17.4 覆盖范围

模式匹配会引导你逐渐使用sealed关键字,这有助于你覆盖了所有可能传入的选择器表达式类型。

如果待被设计的类们(假如有三个)都使用了继承了一个sealed的类或接口,那么进入switch如果case里面只放了两个,那么就会报错

会强制你添加default子句,来防止有误输入的选项。

02 对象传递和引用

Java实际上是有指针的。

不过这些指针都类似与小学生在玩的安全剪刀,并不锋利。可以安全的使用。但是有时会稍显繁琐。

2.1 传递引用

当你将一个引用传给方法后,该引用指向的仍然是原来的对象。可以通过下面这个简单的实验看出这一点。

public class Pass{
    public static void f(Pass h){
        System.out.println(h);
    }
    public static void main(String[] args){
        Pass p = new Pass();
        
        System.out.println(p);
        f(p);
    }
}

他们两个得到的结果是同一个对象。

这说明,他们在传递的是一个对象的引用而不是一个新的对象。

引用别名

引用别名指的是:不止一个引用被绑定到了同一个对象上的情况。

public class Alias1{
    private int i;
    public Alias1(int i1){
        i = i1;
    }
    public static void main(String[] args){
        Alias1 x = new Alias1(7);
        Alias1 y = x;
        
        System.out.println("x: " + x.i);
        System.out.println("y: " + y.i);
        
        x.i++;
        
        System.out.println("x: " + x.i);
        System.out.println("y: " + y.i);
        
    }
}
x: 7
x: 7
X: 8
X: 8

y并不想被改变,但是它由不得自己。

如果你在方法调用的过程中必须修改参数,同时又不想改变该参数在方法外部的状态,那么就要通过在方法内部复制出一个参数的副本的方式进行保护。这是本章的大部分内容的主题。

标签:case,Java,String,System,Edition,println,public,Advanced,out
From: https://www.cnblogs.com/qiantaosama/p/16733188.html

相关文章