Java

醉酒当歌 提交于 2019-12-06 05:53:15

Java笔记

UML

统一建模语言

面向对象三大特征

一.封装性

类的内部信息不能被外部程序直接访问

但是可以用该类提供的方法(Method)对隐藏信息进行操作和访问

(注意,private成员只是不能被直接访问)

封装步骤

1.修改属性的可见性:

​ 改为private

2.创建公有方法:

​ getter方法/setter方法

​ (分别用于属性的读/写)

Mydate d = new MyDate();

d.setDay(31);
d.setDay(d.getDay()+1);
3.在getter/setter方法中加入属性控制语句:

​ 对属性值的合法性进行判断

​ (不懂,判断什么合法性?这条看着像硬凑上去的)

二.继承性(Inheritance)

表示关系常用:is-a

父类更通用(一般特性),子类更具体(自身特性)

想象一棵树

三.多态性

不同对象对于同一个方法实现不同的行为

实际操作

创建项目\(\rightarrow\)新建类 guagua.java\(\rightarrow\)编译\(\rightarrow\)得到guagua.class

一个类对应一个文件

package shipping.reports;

import shipping.domain.*;
import java.util.List;
import java.io.*;



pubilc class Guagua {
    private String salutation;
    Guagua(String S){
        salutation = S;
    }
    public void guagua(String C) {
        System.out.println(salutation + " " + C);
    }
    //out 是 System 类的一个static属性,它的类型是PrintStream
    //PrintStream 是 java.io 包里定义的一个类
}

public class TestGuagua {
    public static void main(String[] args){
        Guagua hello = new Guagua("Hello");
        hello.guagua("World");
    }
}
//提供输入参数,该参数就存入字符串中args[]中
//

标记(token)

return 0 三个标记

return0 一个标记

词法分析器的"贪婪性"

j = i+++++i;
j = i++ + ++i;

类型

默写一下基本类型?

boolean

char

byte(8),short(16),int(32),long(64) (bits)

注意一下,8 bits 代表 \(-2^7 to 2^7-1\)

整数型默认为int

float(32),double(64) (bits)

浮点数默认是double

String 是一个类

引用类型

Primitive Variable

byte x =7;

Referenve Variable

Dog myDog = new Dog();

"Java中唯一的对象引用字面值(literals)是null"

这句话的意思就是,如果现在我们要写一个引用类型,然后现在其实并没有什么要引用的东西,我们就直接写个null,但是不能写别的东西,比如123,321这种东西(C++貌似就可以)

String s = null;也可以

现在又讲到堆(Heap)和栈(Stack)

栈用来存指令,堆用来存实例;

对象实例在heap中进行分配,然后呢在stack中保存一个4字节的heap的内存地址(这一部分好好玩,和我想象的一样);

然后再来说一下,栈里到底存什么:

1.基本数据类型,也就是刚才默写的那些东西啦~;

2.指令代码:函数方法属于指令;

3.对象的引用地址;

4.常量.也就是final 量?

变量生命周期

1.成员变量

类被实例化的时候创建

没有赋值的话是会有默认值的

2.局部变量

静态成员变量的初始化要先于非静态成员变量

class F{
    int x = 20;//被F的构造函数调用前,x被设置为20;
    static int y = 30;//在F被加载时设置为30;
}

局部变量不会被自动赋值

等一下,赋值这个东西...

public class LocalVariable{
    public static void main(String[] args){
        String[] s = new String[2];//可以,初值为null
        String[] s;//不可以
        System.out.println(s[0]);
    }
}

方法参数(Method parameter)

1.定义传入方法的参数

2.当调用该方法时,新变量被创建,生命周期持续到方法结束

这一块不太懂,不知道这个方法参数应该怎么放

在那里写这个所谓的方法参数?方法参数指的具体是什么

3.类变量

即静态变量

一看就是,和类同生同灭

"无论有多少对象,类变量始终只有一个拷贝,被多个对象共享"

初始化方法和成员变量相同,对

final变量

这个东西跟const没设么区别

如果一个final变量是对一个对象的引用,其引用必须相同,但对象本身可以不同

什么意思,这句话?

引用一个对象,引用必须相同,什么意思

是指我本来指向了一个地址,然后现在那个地址里的对象都换了,但是地址必须还指向那里的意思嘛??

class Walrus{
    int weight;
    Walrus(int w){
        weight = w;
    }
}
class Tester{
    final Walrus w1 = new Walrus(1500);
    void test() {
        w1 = new Walrus(1400); //不合法的
        w1.weight = 1800;//合法的
    }
}
public void getValue(final int a){
    a = 10;//wrong!
}
public void getValue(final Contract c){
    c.hourSpanName = "aa";//right
}
所以意思就是说,某类(并且是final)的里面的局部变量是可以被改变的
...对吧?

数组

通俗易懂的一段话:

在java中数组是对象,比如int是基本型,但是int[]是对象

数组的声明没有创建数组对象,只创建了对数组对象的引用

数组元素所占用的内存是通过new或者初始化有系统动态分配的

数组具体怎么用我们就...先不说啦,感觉很简单

String[] a = new String[]{"x","y","z"};

int[] ages;

ages = new int[]{1,2,3,4,5};

关于heap和stack

int a = 3;//stack memory
int[] b = {1,2,3,4,5};//stack里面有int[]b的地址
                    //heap里面有1,2,3,4,5的内存

数组长度

int len = i.length;

用new创建的变量都是引用型变量

Shirt myShirt = new Shirt();
Shirt [] shirts = {new Shirt(),new Shirt(),new Shirt()};

其中stack中存shirts和myShirt的地址
heap里面存shirts里面三个新的Shirt的地址,然后继续存它们的具体值,还有myShirt的具体值。(看图)
   

二维数组

一旦数组被创建,就不能修改长度(和C++一样)

但是可以写:

int Array[] = new int[6];
Array = new int[10]; 

运算符

instanceof 判断已给的对象是否是某个类或者是接口

等一下 接口到底是啥啊??

右移运算符

算术右移,有符号,>>

逻辑右移,无符号,>>>,最高位补0,只允许对int和long型,byte型会被扩展成int型

表达式类型

表达式中,char被扩展成int

隐式转换

基本类型转换

变宽转换是合法的,变窄转换是不合法的

引用转换

Oldtype x = new Oldtype();
Newtype y = x;
//Oldtype 貌似是 Newtype的 子类

显示转换

强制转换导致信息损失,需要显示转换

long BigValue = 99L;
int squashed = bigValue;
int squashed = (int)bigValue;
//所以显式转换就是...加“(类型)”??
public void doSomething(Employee e){
    if(e instanceof Manager){
        Manager m = (Manager) e;
        System.out.println("This is the magager of"+m.getDepartment());
    }
}
//if you do not make the cast,an attempt to execute e.getDepartment() would fail,because the compiler cannot locate a method called getDepartment in the Employee class
$,abcd$可以作为java标识符
    
char[] a = {'1','2','3'};
char a[] = {'1','2','3'};
都是合法的
    (?)

基本

int random = (int)(Math.random()*10);


Scanner input = new Scanner(System.in);
int num = input.nextInt();

"switch(表达式)支持字串、枚举的语法糖"

“JDK1.5之前switch只支持byte,short,char,int”

“JDK1.5之后的自动拆箱,对应的这四种基础类型的封装类型类也同样支持Byte,Short,Character,Integer“

对不起看不懂,还反编译

算了...

switch支持String,其实是支持String的hash值

本质上是switch-int结构

并且利用equals方法来放置hash冲突的问题

最后利用switch-byte精确匹配

特殊循环控制

带标号的continue语句 和 带标号的break语句

这两个语句用来代替goto语句

outer:
    do{
        statement;
        do{
            statement;
            if(boolean expression){
                break outer;
            }
            else if(boolean expression){
                continue outer;
            }
            statement;
        } while(boolean expression);
        statement;
    } while(boolean expression);

使用增强的for循环

public void printElement(int[] list){
    for(int element : list){
        System.out.println(element);
    }
}
privete Map<String,Integer>stockMap = new HashMap();
for(Object i:stockMap.keySet()){
    System.out.println("代号:"+i+",数量:"+stockMap.get(i));
}

类和对象

类包括:

​ 字段field:对象包含的数据

​ 方法

​ 构造器(也就是构造函数)

​ 初始化程序块

​ 嵌套类(inner class)

类的修饰符

public:如果没写public 就只能在自己所属的包里访问

abstract:不能实例化

final:没有子类

类不可以是private和protected

包(package) 是用于区别类

java中的一个包相当于系统中的一个文件夹

protected 可以被子类的实例、同一个包内的所有类访问

构造器

其实就是构造函数

public class A{
    private int x;
    public Thing(){
        x = 233;
    }
    public Thing(int new_x){
        x = new_x;
    }
    public int getX(){
        return x;
    }
    public void setX(int new_x){
        x = new_x;
    }
}

如果不写构造器的话,系统自动创建

但如果写了带参数的构造器,系统不会帮忙创造一个不带参数的构造器

构造器之间的相互调用(使用this)

public class Hello{
    String title;
    int value;
    public Hello(){
        title+="Hello";
    }
    public Hello(int value){
        this();//必须在第一行调用,不能使用Hello();
        this.value = value;
    }
    public Hello(String title,int value){
        this(value);
        this.title += title;
    }
}

初始化块

不知道在说什么,不想看

public class InitializationBlock{
    private int x;
    static double d = 3.14;
    //非静态初始化块:在创建对象时执行(先于构造器);
    {
        x = 5;
        System.out.println("字段x = "+x);
    }
    //静态初始化块:仅在类被加载时执行一次;
    static{
        int x = 10;//静态初始化块中的局部变量
        System.out.println("局部变量x = "+ x);
        //静态初始化块中,this.x不可用
        System.out.println("静态字段d = "+ d);
    }
    public static void main(String[] args){
        new InitializationBlock();
    }
}

起名可以用字母,'**_','$**'开头

类的方法

静态方法

public class Count {
    private int serialNumber;
    private static int counter = 0;
    
    public static int getTotalCount() {
        return counter;
    }
    
    public Count() {
        counter++;
        serialNumber = counter;
    }
}

public class TestCounter {
    public static void main(String[] args) {
        System.out.println("Number of counter is " + Count.getTotalCount());//输出了0
        Count count1 = new Count();
        System.out.println("Number of counter is "+ Count.getTotalCount());//输出了1
    }
    //应该直接用类名来调用静态方法
}
class SomeClass {
    static int i = 48;
    int j = 1;
    
    public static void main(String args[]) {
        i += 100;
        // j *= 5;
    }
}
import java.awt.*;

public class MyFrame extends Frame {
    MyFrame() {
        setSize(300,300);
    }
    
    public static void main(String args[]) {
        MyFrame theFrame = new MyFrame();
        theFrame.setVisible(true);
        
    }
}
// 不知道写这一段东西是干嘛的
public class refValExample {
    
    static void Change(int[] pArray) {
        pArray[0] = 888;
        pArray = new int[] {-3,-1,-2,-3,-4};
        System.out.println("方法内,第一个元素是:"+pArray[0]);//-3
    }
    
    public static void main(String[] args) {
        int[] arr = {1,4,5};
        System.out.println("调用方法之前,第一个元素是:"+arr[0]);//1
        Change(arr);
        System.out.println("调用方法之后,第一个元素是:"+arr[0]);//888
    }
}

包装类

Java collection类中的元素必须为objects

List<Integer> a = new ArrayList<Integer>();
int i = 5;
Integer itg = new Integer(i);

Integer jtg = new Integer(6);
int j = jtg.intValue();

//long转为Long
long l = 8;
Long lng = new Long(l);

//Long转long
Long gng = new Long(9);
long g = gng.longValue();

Integer i1 = Integer.valueOf(42);
Integer i2 = Integer.valueOf("42");

Boolean b1 = Boolean.valueOf(true);
Boolean b2 = Boolean.valueOf("true");

Long n1 = Long.valueOf(42000000L);
Long n2 = Long.valueOf("42000000L");

int i = Integer.parseInt("42");
boolean b = Boolean.parseBoolean("true");
double d = Double.parseDouble("3.14");

自动装箱的例子

List<Integer> li = new ArrayList<Integer>();
for(int i = 1;i<50;i++)li.add(i);
//等价于li.add(Integer.valueOf(i));
public static int sumEven(List<Integer>li) {
    int sum = 0;
    for(Integer i:li){
        if(i%2==0){ //等价:if(i.intValue()%2==0)
            sum += i;//等价:sum += i.intValue();
        }
    }
    return sum;
}

static

1.在类被加载的时候,就会加载被static修饰的部分

2.静态对象与实例对象相对

静态变量

是由static修饰的成员变量,又叫做类变量。说明这个变量属于类而不是属于对象

内存:则它在内存中只存在一份。JVM为静态变量分配一次内存空间。

实例变量

指这个变量是属于某个具体的对象的。

内存:创建几次对象,就有几次成员变量。

不要通过对象的方式去访问静态变量或者静态方法

静态不能访问非静态,非静态可以访问静态。(很常见的例子)

静态方法

不存在this关键字

静态是由类的加载而加载,this是由对象的创建而存在的。所以静态比对象优先存在。

多线程

分时利用CPU,也叫并发

每一次调用start()相当于:放入等待队列,等待CPU调度,处于就绪状态

方法run()称为线程体,它包含了执行线程的内容

只有用start()方法来启动线程,才能实现真正的多线程运行,

将run()方法当作普通方法的方式调用,程序仍然按照顺序进行.

实现多线程的两种方法

1.继承Thread类

Thread类在java.lang包中定义

一个类继承Thread类同时覆写了本类中的run()方法 \(\rightarrow\) 用start()启动线程 \(\rightarrow\)实现多线程操作

此方法的局限:一个类只能继承一个父类

$\rightarrow $Runnable 接口为非Thread子类的类提供了一种激活方式

2.实现Runable接口

package org.runnable.demo;
class MyThread implements Runnable {
    private String name;
    public MyThread(String name) {
        this.name = name;
    }
    public void run() {
        for(int i=0;i<100;i++) {
            System.out.println("gua gua stand up!!");
        }
    }
}

实现run()方法,用new Thread(Runnable target).start()方法来启动

在使用Runnable定义的子类中没有start()方法,只有Thread类才有

public class Test {
    public static void main(String[] args) {
        Runner1 runner1 = new Runner1();
        Runner2 runner2 = new Runner2();
        
        Thread thread1 = new Thread(runner1);
        Thread thread2 = new Thread(runner2);
        
        //thread1.start();
        //thread2.start();
        thread1.run();
        thread2.run();
    }
}
class Runner1 implements Runnable {
    public void run() {
        for(int i=0;i<100;i++) {
            System.out.printlen("Runner1 : i");
        }
    }
}
class Runner2 implements Runnable {
    public void run() {
        for(int i=0;i<100;i++) {
            System.out.printlen("Runner2 : i");
        }
    }
}  

Packages

java.awt 图形,用户界面。

java.lang 提供对Java编程语言设计至关重要的类。

java.io 通过数据流、序列化和文件系统提供系统输入输出。

java.util 包含集合框架,旧集合类,事件模型,日期和时间设施。

Class

异常处理

java中异常被封装成了一个类

出现问题时,会创建异常类对象并且抛出异常相关信息

自定义的异常类

创建自定义的异常类需要继承自Exception类

并提供含有一个String类型形参的构造方法,该形参就是一场的描述信息,

可以通过getMessage()方法获得。例如:

public class NewException extends Exception{
    public NewException(String s){//这个s就是自定义的精髓所在,想传啥传啥
            super(s);
    }
}

Throwable类是所有异常类的超类

Exception类继承自Throwable类

RuntimeException类是运行异常类,继承自Exception类,它以及它的子类只能在运行过程中存在

JAVA虚拟机

Java Virtual Machine

包括

一套字节码(Bytecode)(目标代码)指令集:

操作码(8位二进制,高位bits在低字节)+操作数

一组寄存器

若JVM定义较多的寄存器,则减少对栈和内存进行访问,提高运行速度

但如果JVM的寄存器比CPU的寄存器多,则JVM运行速度实际降低

JVM设置了4个常用的寄存器

pc 程序计数器:记录程序的执行

optop 操作数栈顶指针

frame 当前执行环境指针

vars 指向当前第一个局部变量的指针

optop,frame,vars用于记录指向Java栈区的指针

寄存器均为32位

一个栈

JVM模拟真实计算机,作为基于栈结构的计算机,Java栈是储存JVM存储信息的主要方法

栈框架

一个垃圾回收堆

一个存储方法域

Java数组被当作Object处理

try-catch

https://blog.csdn.net/qq_34427165/article/details/83929470

try {
  //可能出现异常的代码
} catch(异常类名A e){
  //如果出现了异常类A类型的异常,那么执行该代码
} ...(catch可以有多个)
finally {
 //最终肯定必须要执行的代码(例如释放资源的代码)
}

代码执行的顺序:

1.try内的代码从出现异常的那一行开始,中断执行

2.执行对应的catch块内的代码

3.继续执行try catch结构之后的代码

1.儿子不能比父亲的本事大

2.儿子要比父亲开放

3.儿子不能比父亲惹更大的麻烦(子类的异常的类型不能是父类的异常的父类型)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!