Java的this关键字和Builder模式

0、第一种用途:this指向当前对象的引用

this指向调用当前方法的对象。

public class Age {
    // 年龄
    int number = 10;

    // 生日
    Age birthday() {
        sing(); // 等同于 this.sing();
        number++; // 等同于 this.number++;
        return this;
    }

    // 唱生日歌
    void sing() {
        System.out.println("祝你生日快乐...");
    }

    public static void main(String[] args) {
        Age age = new Age();
        age.birthday().birthday().birthday();
        System.out.println("现在年龄为:" + age.number);// 结果为:13
    }
}

在方法中调用当前类其它字段或方法需要用到this,如this.sing(),为了方便,编译器允许将this省略。

birthday()方法返回this,表示返回当前对象。所以可以连续调用age.birthday().birthday().birthday()

记住:static方法里没有this,因为this指向当前调用的对象,而static方法(静态方法)不属于任何对象,只属于类。


1、第二种用途:this调用构造方法

在构造方法中,this后面跟参数可以调用另一个构造方法,编译器会根据参数列表自动匹配到相应的构造方法。如this(name, age);

public class Student {
    // 姓名
    String name;
    // 年龄
    int age;
    // 性别
    String sex;

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

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

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

2、Builder模式(构造者模式)

Builder模式也叫构造者模型,顾名思义就是通过多个参数构造出一个新的对象。Builder模式非常常见,在日后的开发中经常会使用到Builder模式的类库。

Builder模式常常用于类字段非常多,而且参数往往不是必须的情况下。(这里为了方便阅读就只有三个参数)。

public class Student {
    String name;
    int age;
    String sex;

    private Student(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
    }

    public static class Builder {
        String name;
        int age;
        String sex;


        // name是必须的
        public Builder(String name) {
            this.name = name;
        }

        public Builder age(int age) {
            this.age = age;
            return this;
        }

        public Builder sex(String sex) {
            this.sex = sex;
            return this;
        }

        public Student build() {
            return new Student(this);
        }
    }

    public static void main(String[] args) {
         // 创建构造者
        Student.Builder builder = new Student.Builder("张三")
                .age(18)
                .sex("女");
        // 构造者创建目标对象
        Student s1 = builder.build();

        // 简约写法
        Student s2 = new Student.Builder("张三")
                .age(18)
                .sex("女")
                .build();
    }
}

这里Student类里面有个内部类Builder,也叫做嵌套类(static修饰的内部类叫做嵌套类)。

内部类Builder和外部类Student持有相同的字段。

外部类Student的构造方法是private修饰的,在其它类里面无法直接通过new创建Student对象。构造方法参数接收的是内部类对象引用: private Student(Builder builder)

Builder内部类的age(int age)sex(String sex)方法都返回this(Builder对象引用)。

内部类Builder通过build()方法里new Student(this)创建外部类Student对象。


嵌套类就是构造者,通过它来创建Student对象。如下:

// 创建构造者
Student.Builder builder = new Student.Builder("张三")
                .age(18)
                .sex("女");
// 构造者创建目标对象
Student s1 = builder.build();

// 简约写法
Student s2 = new Student.Builder("张三")
                .age(18)
                .sex("女")
                .build();

创建普通类:new XxxClass(); 创建嵌套类:new OutClass.InnerClass()

3、结语

关注微信公众号:小虎哥的技术博客

下面是一个示例Java程序,用于统计输入的Java源码中出现的关键字的数量,并按照关键字升序进行排序输出: ```java import java.util.*; public class KeywordCounter { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String line; StringBuilder builder = new StringBuilder(); while (!(line = scanner.nextLine()).equals("exit")) { builder.append(line); builder.append("\n"); } String sourceCode = builder.toString(); if (sourceCode.trim().isEmpty()) { System.out.println("Wrong Format"); return; } String[] keywords = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while" }; Map<String, Integer> keywordCountMap = new TreeMap<>(); int startPos = 0; boolean inString = false; boolean inComment = false; while (startPos < sourceCode.length()) { int nextPos; if (inString) { nextPos = sourceCode.indexOf("\"", startPos + 1); if (nextPos == -1) { break; } } else if (inComment) { nextPos = sourceCode.indexOf("*/", startPos + 1); if (nextPos == -1) { break; } inComment = false; startPos = nextPos + 2; continue; } else { nextPos = sourceCode.length(); int commentStartPos = sourceCode.indexOf("/*", startPos); int lineCommentStartPos = sourceCode.indexOf("//", startPos); if (lineCommentStartPos != -1 && (commentStartPos == -1 || lineCommentStartPos < commentStartPos)) { nextPos = lineCommentStartPos; } if (commentStartPos != -1 && (lineCommentStartPos == -1 || commentStartPos < lineCommentStartPos)) { nextPos = commentStartPos; inComment = true; } for (String keyword : keywords) { int keywordPos = sourceCode.indexOf(keyword, startPos); if (keywordPos != -1 && keywordPos < nextPos) { int endPos = keywordPos + keyword.length(); if (endPos == sourceCode.length() || !Character.isJavaIdentifierPart(sourceCode.charAt(endPos))) { keywordCountMap.put(keyword, keywordCountMap.getOrDefault(keyword, 0) + 1); } } } } startPos = nextPos + 1; } for (Map.Entry<String, Integer> entry : keywordCountMap.entrySet()) { System.out.printf("%d\t%s\n", entry.getValue(), entry.getKey()); } } } ``` 该程序首先从标准输入读取输入的Java源码,然后使用一个字符串数组保存Java关键字。接着,程序使用一个`Map`对象统计源码中出现的每个关键字的数量,并在统计时忽略了注释和字符串中出现的关键字。最后,程序按照关键字升序进行排序输出统计结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小虎哥的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值