Java 1.廖雪峰教程

使用IDE
Java > Compiler “Use default compliance settings”并钩上“Enable preview features for Java 15”
这里要和实际下载的JDK一致,这里下载的是Java SE16 ,所以不用勾选15
否则报错:

错误: 加载主类 Main 时出现 LinkageError
java.lang.UnsupportedClassVersionError:

run as 无 Java Application
无main函数,或主函数报错

不写public,也能正确编译,但是这个类将无法从命令行执行。

Java入口程序规定的方法必须是静态方法,方法名必须为main,括号内的参数必须是String数组。

class名 首字母大写, method 名 首字母小写

= 仅赋值,不涉及地址

要特别注意,整数由于存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会出错,却会得到一个奇怪的结果

char 单引号 String 双引号
" 表示字符"
’ 表示字符’
\ 表示字符
\n 表示换行符
\r 表示回车符
\t 表示Tab

%d 格式化输出整数
%x 格式化输出十六进制整数
%f 格式化输出浮点数
%e 格式化输出科学计数法表示的浮点数
%s 格式化字符串

method的引用类型(除int,doule等值类型外的所有类型)参数的传递,传的是同个地址

**构造方法:**构造方法的名称就是类名。构造方法的参数没有限制,在方法内部,也可以编写任意语句。但是,和普通方法相比,构造方法没有返回值(也没有void),调用构造方法,必须用new操作符。

public class Main {
    public static void main(String[] args) {
        Person p = new Person("Xiao Ming", 15);
        System.out.println(p.getName());
        System.out.println(p.getAge());
    }
}
class Person {
    private String name;
    private int age;
    public Person(String name, int age) {  //
        this.name = name;
        this.age = age;
    }    
    public String getName() {
        return this.name;
    }
    public int getAge() {
        return this.age;
    }
}

如果既要能使用带参数的构造方法,又想保留不带参数的构造方法,那么只能把两个构造方法都定义出来:

class Person {
    private String name;
    private int age;
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person(String name) {
        this.name = name;
        this.age = 12;
    }
}

一个构造方法可以调用其他构造方法,这样做的目的是便于代码复用。调用其他构造方法的语法是this(…)

class Person {
    private String name;
    private int age;

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

    public Person(String name) {
        this(name, 18); // 调用另一个构造方法Person(String, int)
    }

    public Person() {
        this("Unnamed"); // 调用另一个构造方法Person(String)
    }
}

String .indexOf() 函数

indexOf(int ch): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。

indexOf(int ch, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。

indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。

indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。

继承
有个特点,就是子类无法访问父类的private字段或者private方法。用protected修饰的字段可以被子类,以及子类的子类所访问。protected关键字可以把字段和方法的访问权限控制在继承树内部super关键字表示父类(超类)。子类不会继承任何父类的构造方法

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Xiao Ming", 12, 89);
    }
}
class Person {
    protected String name;
    protected int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
class Student extends Person {
    protected int score;
    public Student(String name, int age, int score) {
        super(name, age); // 调用父类的构造方法Person(String, int)
        this.score = score;
    }
}

只要某个class没有final修饰符,那么任何类都可以从该class继承

向上转型与向下转型:上下指的是继承树上的位置,父类在上。为了避免向下转换报错,可以用instanceof先判断类型

Person p1 = new Student(); // 向上转型,由于student具有person全部功能,故可以转换
Person p2 = new Person();
Student s1 = (Student) p1; // ok,因为此时p1类型          ==同时为student和person==
Student s2 = (Student) p2; // 报错,因为p2是父类,不具备子类的额外功能,无法转换

多态

Override:即在继承关系中,子类定义了一个与父类方法签名完全相同的方法
Overload:如果传入参数或方法返回值类型不同

多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法
在这种情形下,如果student覆写了person的方法,调用p时,使用的是子类的方法。

Person p = new Student()

可见,多态具有一个非常强大的功能,就是允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码。
在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过super来调用。
final修饰的方法不能被Override。对于final字段,可以在构造方法中初始化

抽象类

如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法

class Person {
    public abstract void run();
}

把一个方法声明为abstract,表示它是一个抽象方法,本身没有实现任何方法语句。因为这个抽象方法本身是无法执行的,所以,Person类也无法被实例化。编译器会告诉我们,无法编译Person类,因为它包含抽象方法。
必须把Person类本身也声明为abstract,才能正确编译它,但仍然无法实例化一个抽象类

abstract class Person {
    public abstract void run();
}

用处:抽象类本身被设计成只能用于被继承,实际上相当于定义了“规范”。子类必须覆写抽象类中的抽象方法。
好处: Person s = new 子类,具体功能取决于子类,但都引用高层类型

接口

所谓interface,就是比抽象类还要抽象的纯抽象接口,因为它连字段都不能有。因为接口定义的所有方法默认都是public abstract的,所以这两个修饰符不需要写出来

interface Person {
    void run();
    String getName();
}

当一个具体的class去实现一个interface时,需要使用implements关键字

class Student implements Person {
    private String name;
    public Student(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println(this.name + " run");
    }
    @Override
    public String getName() {
        return this.name;
    }
}

一个类只能继承自另一个类,不能从多个类继承。但是,一个类可以实现多个interface
接口继承:一个interface可以继承自另一个interface。interface继承自interface使用extends,它相当于扩展了接口的方法。
interface是一个纯抽象类,所以它不能定义实例字段。但是,interface是可以有静态字段的,并且静态字段必须为final类型

interface Hello {
    void hello();
}

interface Person extends Hello {
    void run();
    String getName();
}

在接口中,可以定义default方法。这样可以只让需要修改的子类覆写方法

静态字段和静态方法

静态字段只有一个共享“空间”,所有实例都会共享该字段.无论修改哪个实例的静态字段,效果都是一样的:所有实例的静态字段都被修改了

public class Main {
    public static void main(String[] args) {
        Person ming = new Person();
        Person hong = new Person();
        ming.number = 88;
        System.out.println(hong.number);//88
        hong.number = 99;
        System.out.println(ming.number);//99
    }
}
class Person {
    public static int number;
}

推荐用Person.number而不是用实例.静态字段 访问方法,因为是共享的,所以避免混乱

静态方法内部,无法访问this变量,也无法访问实例字段,它只能访问静态字段

作用域

一个.java文件只能包含一个public类,但可以包含多个非public类。如果有public类,文件名必须和public类的名字相同

final

阻止class被继承;阻止method被覆写;阻止field被重新赋值;也可以修饰局部变量防止重新赋值

内部类

与普通类有个最大的不同,要实例化一个Inner,我们必须首先创建一个Outer的实例,然后,调用Outer实例的new来创建Inner实例示例代码如下

public class Main {
    public static void main(String[] args) {
        Outer a = new Outer("Nested"); // 实例化一个Outer
        Outer.Inner b = a.new Inner(); // 实例化一个Inner
        b.hello();
    }
}
class Outer {
    private String name;
    Outer(String name) {
        this.name = name;
    }
    class Inner {
        void hello() {
        //能使用outer.this 
            System.out.println("Hello, " + Outer.this.name);
        }
    }
}

匿名类 是不必明确定义内部类的一种方法

class outerClass {
    // 定义一个匿名类
    object1 = new Type(parameterList) {
         // 匿名类代码
    };
}

静态内部类 普通内部类前面加static。不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this,但它可以访问Outer的private静态字段和静态方法。(只能访问静态方法和静态字段)

public class Main {
    public static void main(String[] args) {
        Outer.StaticNested sn = new Outer.StaticNested();
        sn.hello();
    }
}
class Outer {
    private static String NAME = "OUTER";
    private String name;
    Outer(String name) {this.name = name;}
    static class StaticNested {void hello() {System.out.println("Hello, " + Outer.NAME);}}
 }

Spring开发

IoC原理:即不在class内new一个对象,而是先定义其类型,然后等外部通过set或构造方法对它赋值
它解决了一个最主要的问题:将组件的创建+配置与组件的使用相分离,并且,由IoC容器负责管理组件的生命周期
一种最简单的配置是通过XML文件来实现

<beans>
    <bean id="dataSource" class="HikariDataSource" />
    <bean id="bookService" class="BookService">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <bean id="userService" class="UserService">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

上述XML配置文件指示IoC容器创建3个JavaBean组件,并把id为dataSource的组件通过属性dataSource(即调用setDataSource()方法)注入到另外两个组件中。

在Spring的IoC容器中,我们把所有组件统称为JavaBean,即配置一个组件就是配置一个Bean。

如果注入的不是Bean,而是boolean、int、String这样的数据类型,则通过value注入

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" />
    <property name="username" value="root" />
    <property name="password" value="password" />
    <property name="maximumPoolSize" value="10" />
    <property name="autoCommit" value="true" />
</bean>

使用Annotation配置,可以完全不需要XML,让Spring自动扫描Bean并组装它们
网站下给了个zip链接,可以运行理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值