Java学习笔记

未懂

static的作用
finalize()方法
接口适配

6.初始化和清理

this

在构造器中调用构造器可以用this关键字,通常当你说 this,意味着"这个对象"或"当前对象",它本身生成对当前对象的引用。

import java.util.*;
class Flower {
    int petalCount = 0;
    String s = "initial value";

    Flower(int petals) {
        petalCount = petals;
        System.out.println("Constructor w/ int arg only, petalCount = " + petalCount);
    }

    Flower(String ss) {
        System.out.println("Constructor w/ string arg only, s = " + ss);
        s = ss;
    }

    Flower(String s, int petals) {
        this(petals);
        //- this(s); // Can't call two!
        this.s = s; // Another use of "this"
        System.out.println("String & int args");
    }

    Flower() {
        this("hi", 47);
        System.out.println("no-arg constructor");
    }

    void printPetalCount() {
        //- this(11); // Not inside constructor!
        System.out.println("petalCount = " + petalCount + " s = " + s);
    }
}
public class MyClass {
    public static void main(String[] args)
    {
        Flower x = new Flower();
        x.printPetalCount();
    }
}
构造器初始化
import java.util.*;
class T
{
    int i;
    T()
    {
        i = 10;
    }
}
public class MyClass {
    public static void main(String[] args){
        T x = new T();
        System.out.println(x.i);
    }
}

output:
10
Integer和int的区别

int是基本数据类型,存储的是数值,而Integer是引用类型,实际是一个对象,存储的是引用对象的地址

Integer a = new Integer(100),b = new Integer(100);
System.out.println(a==b);

output:
false

7.封装

一个java源代码文件下只能含有一个public类,其他的类是为主类提供支持的,在包之外无法访问到这些为主类提供支持的类

访问权限

public:无论是谁,无论在哪,都可以访问它。
包访问权限(默认,不加修饰):同一包内的其他类皆可访问。
private:除了包含该成员的类,其他任何类都无法访问这个成员。同一包中的其他类无法访问 private 成员,因此这等于说是自己隔离自己。

//private举例
class Sundae {
    private Sundae() {}
    static Sundae makeASundae() {
        return new Sundae();
    }
    void f()
    {
        System.out.println("This is a test!");
    }
}
public class MyClass {
    public static void main(String[] args){
        Sundae x = Sundae.makeASundae();
        x.f();
    }
}
包访问权限类中定义Public 构造器

当你定义一个具有包访问权限的类时,你可以在类中定义一个 public 构造器,在一个具有包访问权限的类中定义一个 public 的构造器并不能真的使这个构造器成为 public。

8.复用

继承式复用

对于基类的构造函数是有参的情况,继承的派生类必须使用super关键字和适当的参数列表显式地编写对基类构造函数的调用:

class Game {
    Game(int i) {
        System.out.println("Game constructor");
    }
}

class BoardGame extends Game {
    BoardGame(int i) {
        super(i);
        System.out.println("BoardGame constructor");
    }
}
public class MyClass {
    public static void main(String[] args){
        BoardGame x = new BoardGame(2);
    }
}

当打算重写而不是重载一个方法时,可以使用注解@override

//像这样
class Homer{
    float doh(float f)
    {
        System.out.println("float");
        return f;
    }
    char doh(char c)
    {
        System.out.println("char");
        return c;
    }
}
class Lisa extends Homer
{
    @Override float doh(float m)
    {
        System.out.println("void");
        return m;
    }
}

对于类自己内部的方法,自己调用不需加前缀。

class T
{
    int i;
    void f(int x)
    {
        i = x;
    }
    void set()
    {
        f(10);
    }
}
final

使用 final 方法可以给方法上锁,防止子类通过覆写改变方法的行为。这是出于继承的考虑,确保方法的行为不会因继承而改变。

当说一个类是 final (final 关键字在类定义之前),就意味着它不能被继承。

9.多态

@Override

一般用途:
帮助自己检查是否正确的复写了父类中已有的方法
告诉读代码的人,这是一个复写的方法

在面向对象中,私有方法不可以复写,根本就不存在复写私有方法的概念。私有方法本身就是为了封装在类内部,不希望别人来更改或者外部引用。

10.接口

抽象类和接口的区别

Java学习笔记_第1张图片

接口和继承

通常来说,extends 只能用于单一类,但是在构建接口时可以引用多个基类接口。注意到,接口名之间用逗号分隔。

10.内部类

创建内部类对象
class T
{
    void f()
    {
        System.out.println("NJN");
    }
    public class t
    {
        public T cre()
        {
            return T.this;
        }
    }
}
public class MyClass{
    public static void main(String[] args){
        T x = new T();
        T.t a = x.new t();
        a.cre().f();
    }
}

output:
NJN
继承内部类

在继承内部类的时候,不能使用默认构造器,必须重写

class Contents{
    class c
    {

    }
}
class x extends Contents.c
{
    x(Contents a)
    {
        a.super();
    }
}
覆写内部类

当继承了某个外部类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。

class Egg {
    private Yolk y;
    protected class Yolk {
        public Yolk() {
            System.out.println("Egg.Yolk()");
        }
    }
    Egg() {
        System.out.println("New Egg()");
        y = new Yolk();
    }
}
class B extends Egg
{
    public class Yolk {
        public Yolk() {
            System.out.println("BigEgg.Yolk()");
        }
    }
    Yolk y = new Yolk();
}
public class MyClass{
    public static void main(String[] args){
        new B();
    }
}

output:
New Egg()
Egg.Yolk()
BigEgg.Yolk()

12. 集合

LinkedList

LinkedList 还添加了一些方法,使其可以被用作栈、队列或双端队列(deque) 。在这些方法中,有些彼此之间可能只是名称有些差异,或者只存在些许差异,以使得这些名字在特定用法的上下文环境中更加适用(特别是在 Queue 中)。例如:

  • getFirst() 和 element() 是相同的,它们都返回列表的头部(第一个元素)而并不删除它,如果 List 为空,则抛出 NoSuchElementException 异常。 peek() 方法与这两个方法只是稍有差异,它在列表为空时返回 null 。
  • removeFirst() 和 remove() 也是相同的,它们删除并返回列表的头部元素,并在列表为空时抛出 NoSuchElementException 异常。 poll() 稍有差异,它在列表为空时返回 null 。
  • addFirst() 在列表的开头插入一个元素。
    offer() 与 add() 和 addLast() 相同。 它们都在列表的尾部(末尾)添加一个元素。
  • removeLast() 删除并返回列表的最后一个元素。
Map的遍历
//使用entry
//使用entry
for (Map.Entry<Integer,Integer> e: mp.entrySet())
    System.out.println(e.getKey()+" "+e.getValue());
//使用iterator
Iterator<Map.Entry<Integer,Integer>> it = mp.entrySet().iterator();
while (it.hasNext())
{
    Map.Entry<Integer,Integer> x = it.next();
    System.out.println(x.getKey() + " " + x.getValue());
}
//使用for-in键值对
for (Integer i: mp.keySet())
    System.out.println(i + " " + mp.get(i));
for (Integer i: mp.values())
    System.out.println(i);

20.泛型

泛型擦除
// generics/HasF.java

public class HasF {
    public void f() {
        System.out.println("HasF.f()");
    }
}
//----------------------------------
// generics/Manipulation.java
// {WillNotCompile}

class Manipulator<T> {
    private T obj;

    Manipulator(T x) {
        obj = x;
    }

    // Error: cannot find symbol: method f():
    public void manipulate() {
        obj.f();
    }
}

public class Manipulation {
    public static void main(String[] args) {
        HasF hf = new HasF();
        Manipulator<HasF> manipulator = new Manipulator<>(hf);
        manipulator.manipulate();
    }
}

//这里就会编译错误,因为擦除,Java 编译器无法将 manipulate() 方法必须能调用 obj 的 f() 方法这一需求映射到 HasF 具有 f() 方法这个事实上。为了调用 f(),我们必须协助泛型类,给定泛型类一个边界,以此告诉编译器只能接受遵循这个边界的类型。这里重用了 extends 关键字。由于有了边界,下面的代码就能通过编译:
public class Manipulator2<T extends HasF> {
    private T obj;

    Manipulator2(T x) {
        obj = x;
    }

    public void manipulate() {
        obj.f();
    }
}

多线程

多线程的三种实现方式
import java.lang.reflect.Array;
import java.util.*;
import java.nio.file.*;
import java.net.URI;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
//通过继承Thread来创建线程
class MyThread extends Thread
{
    int i = 0;
    @Override
    public void run()
    {
        while (i<5) {
            System.out.println(this.getName()+"    i的值   "+i);
            i++;
        }
    }
}
//通过实现 Runnable 接口来创建线程
class myRun implements Runnable
{
    int i;
    @Override
    public void run()
    {
        try {
            while (i++ < 5) {
                System.out.println(Thread.currentThread().getName() + "     i的值     " + i);
            }
            Thread.sleep(50);
        }catch (InterruptedException e)
        {
            System.out.println("Thread " + " interrupted.");
        }
    }
}
//通过 Callable 和 Future 创建线程
//1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
//2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
//3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
//4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
class ca implements Callable<Integer>
{
    @Override
    public Integer call() throws Exception
    {
        int i = 0;
        for (;i < 5;i ++)
            System.out.println(Thread.currentThread().getName());
        return i;
    }
}
public class MyClass{
    public static void main(String[] args){
        MyThread x = new MyThread();
        x.setName("By Thread");
        x.start();

        Thread y = new Thread(new myRun(),"By Runnable");
        y.start();

        FutureTask<Integer> t = new FutureTask<>(new ca());
        new Thread(t,"By Callable and FutureRask").start();
    }
}

非静态内部类(匿名内部类)都会默认持有对外部类的强引用,垃圾回收无效

你可能感兴趣的:(Java学习笔记)