java points[复习]

1 - & 与 && 的区别:

  • &:不管左边是true还是false,右端都会进行运算;
  • &&:当左端为false时,右端不再进行运算;
  • 即在运算时,前面为false,即可判断该条件为false了,后面没必要再算了   ----建议使用 &&.

2 - | 与 || 的区别:

  • |:不管左端,右端照算;
  • ||:左端为true时,右端不用算(最终结果已经可以确定为true了);
  • 建议用 ||

3 - java中内存的基本结构:

4 - this关键字的使用:

  • 1 - 当形参与成员变量重名时,如果在方法内部需要使用成员变量,必须添加this来表明该变量的类成员;
  • 2 - 在任意方法内,如果使用当前类的成员变量或成员方法可以在其前面添加this,增强程序的阅读性;
  • 3 - this可以作为一个类中,构造器相互条用的特殊格式;
public Person(String name){
    this(); //调用本类中的无参构造方法
    this.name = name;
}
public Person(String name, int age){
    this(name); //调用有一个参数的构造方法
    this.age = age;
}

5 - thissuper的区别:

No.区别点thissuper
1 访问属性 访问本类中的属性,如果本类中没有此属性,则从父类中继续查找 访问父类中的属性
2 调用方法 访问本类中的方法 直接访问父类中的方法
2 调用构造器 调用本类构造器,必须放在构造器的首行 调用父类构造器,必须放在子类构造器的首行
4 特殊 表示当前对象 无此概念

6 - 权限修饰符的区别:

  • private :无法被子类继承,也无法被外部类调用;
  • protected :显示的表示可以被子类继承;
  • public : 可以被外部类直接调用;

7 - java中的多态:

Person 父类,有eat(),walk();
Man 和 Woman 为继承了 Person 类的子类,并且都重写了eat()walk()方法,
另外,Woman类中有一个自己的方法,即shooping()

Man m = new Man();
m.eat();
m.walk();
System.out.println();

//*【子类对象的多态性】:父类的引用指向子类对象
Person p1 = new Man(); //向上转型
//虚拟方法调用:通过父类的引用指向子类对象的实体,当调用方法时,执行的是子类重写父类的方法
p1.eat();
p1.walk();

Person p2 = new Woman();
p2.eat();
p2.walk();
Woman w = (Woman)p2; //向下转型
w.shooping();

补充:instanceof:类型判断

//格式:对象p instanceof 类A
if(p1 instanceof Woman){
    //如果p1是Woman类型,则可以转型
    Woman w1 = (Woman)p1;
    w1.shooping();
}

8 - static修饰属性(类变量):

1.由类创建的所有对象,都共用这一个属性
2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用。vs 实例变量(非static变量修饰的属性
3.类变量随着类的加载而加载的,而且独一份
4.静态的变量可以直接通过“类.类变量”的形式来调用
5.类变量的加载要早于对象。所以当有对象以后,可以“类.类变量”使用。但是“类.实例变量”是不行的。
6.类变量存在与静态域中。

class SportMan{
    //实例变量(随着对象的创建而被加载的)
    String name;
    int age;
    //类变量
    static String nation;
    
}

8 - static修饰方法(类方法):

1.随着类的加载而加载,在内存中也是独一份
2.可以直接通过“类.类方法”的方式调用
3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法。反之,非静态的方法可以调用静态的属性或静态的方法
>静态的方法内是不可以有this或super关键字的!
注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要早于非静态的结构,被回收也要晚于非静态的结构

>可以简单记住:加了static的方法和变量,可以不new一个对象而直接通过类.方法名类.变量名来调用,例如:

class Black{
    Test.bianliang; //直接调用,而不需要new一个
    Test.fangfa();  //直接调用,而不需要new一个
}
Class Test{
    
    public static int bianliang = 666;

    public static void fangfa(){
        System.out.println("测试方法");
    }
}

9 - 单例模式

【推荐阅读博客】:https://blog.csdn.net/goodlixueyong/article/details/51935526
1.解决的问题:使得一个类只能创建一个对象。
2.如何实现?见如下4步

//饿汉式
public class TestSingleton{
    public static void main(String[] args){
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getINstance();
        System.out.println(s1 == s2);   //比较两个对象的引用是否一样
        //而equal()用来比较两个对象是否一样
    }
}

//只能创建Singleton的单个实例
class Singleton{
    //1.私有化构造器,使得在类的外部不能够调用次构造器
    private Singleton(){
        
    }
    
    //2.在类的内部创建一个类的实例
    private static Singleton instance = new Singleton();
    
    //3.私有化此对象,通过公共的方法来调用
    //4.此公共的方法,只能通过类来调用,因为设置为static的,同时类的实例也必须为static声明的
    public static Singleton getInstance(){
        return instance;
    }
}
ture
//懒汉式:可能存在线程安全问题
public class TestSingleton1{
    public static void main(String[] args){
        Singleton1 s1 = Singleton1.getInstance();
        Singleton1 s2 = Singleton1.getINstance();
        System.out.println(s1 == s2);
    }
}

class Singleton1{
    //1.私有化构造器
    private Singleton1(){
        
    }
    
    //2.在类的内部创建一个类的实例,并使其为私有和静态的
    private static Sintleton1 instance = null;
    
    //3.返回对象
    public static Singleton1 getInstance(){
        if(instance == null){
            instance = new Singleton1();
        }
        return instance;
    }
}

10 - final修饰

  • 1.final修饰类:这个类就不能被继承;
  • 2.final修饰方法:这个方法不能被子类重写;
  • 3.final修饰属性:此属性就是一个常量,一旦初始化,就不能再赋值。习惯上常量有大写字母表示;

11 - java集合

Collection接口:

  • Set:元素无序、不可重复的集合;
  • List:元素有序,可重复的集合;

Map接口:具有映射关系“key-value”的集合;

12 - java中的接口

  • 1.接口可以看作是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。
  • 2.接口是没有构造器的;
  • 3.接口定义的就是一种功能。 此功能可以被类所实现(implements);
比如:class CC extends DD implements AA
  • 4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。若没有重写,则仍为抽象类;
  • 5.类可以实现多个接口。 ----- java中类的的继承是单继承的;
  • 6.接口与接口之间也是继承的关系,而且可以实现多继承。
  • <5、6是面试的重点>

13 - 集合的使用

  • Collection接口:
  • List接口:存储有序的,可以重复的元素 ---- 相当于“动态”数组;
    》添加进List集合中的元素(或对象)所在的类一定要重写equals()方法;
  • ArrayList(主要的实现类)
  • LinkedList(链表形式的实现类,更适用于频繁的插入、删除操作)
  • Vector(古老的实现类、线程安全的,但效率要低于ArrayList)
  • Set接口:存储无序的,不可重复的元素 ---- 相当于高中的集合概念
    》添加进Set集合中的元素所在的类一定要重写equals()hashCode()方法;
  • HashSet(主要的实现类)
  • LinkedHashSet(是HashSet的子类,当我们遍历集合元素时,是按照添加进去的顺序实现的)
  • TreeSet(可以按照添加进集合中的元素的制定属性进行排序)
  • 要求TreeSet添加进的元素必须是同一个类的!
  • 两种排序方式:
  • 自然排序:
  • ①要求添加进TreeSet中的元素所在类implementS Comparable接口
  • ②重写compareTo(Object obj),在此方法内指明按照元素的哪个属性进行排序
  • ③向TreeSet中添加元素即可,若不实现此接口,会报运行时异常
  • 定制排序:
  • ①创建一个实现Comparator接口的实现类的对象,在实现类中重写Comparator的方法
  • ②在此compare()方法中指明按照元素所在类的哪个属性进行排序
  • ③将此实现Comparator接口的实现类的对象作为形参传递给TreeSet的构造器中
  • ④向TreeSet中添加元素即可,若不实现次接口,会报运行时异常
  • 》要求重写的compareTo()或者compare()方法与equals()和hashCode()方法保持一致。
  • Map接口:存储“键-值”对的数据 ---- 相当与高中的“函数 y = f(x)”
  • key是不可重复的,使用Set存放。value可以重复,使用Collection来存放的。一个key-value构成一个entry(Map.Entry),entry使用Set来存放
  • HashMap:主要的实现类,可以添加null键,null值
  • LinkedHashMap:是HashMap的子类,可以按照添加进Map的顺序实现遍历
  • TreeMap:需要按照key所在类的制定属性进行排序,要求key是同一个类的对象,对key考虑使用自然排序 或 定制排序
  • HashTable:是一个古老的实现类,线程安全的,不可以添加进null键,null值;不建议使用。
  • 子类:Properties:重用来处理属性文件(如数据库的配置文件)

14 - java多线程

//使用实现Runnable接口的方式,售票
/**
 * 此线程会存在线程安全问题
 * 2.如何来解决线程的安全问题?
 *     必须让一个线程操作共享数据完毕后,其他线程才有机会参与共享数据的操作
 * 
 * 3.java如何实现线程的安全:线程的同步机制
 *     
 *         方式一:同步代码块
 *         synchronized(同步监视器){
 *             //需要被同步的代码(即为操作共享数据的代码)
 *         }
 *         1.共享数据:多个线程共同操作的同一个数据(变量)
 *         2.同步监视器:由一个类的对象来充当。哪个线程获取此监视器,谁就执行大括号里被同步的代码。俗称:锁
 *         要求:所有的线程必须共用同一把锁!
 *         注:在实现的方式中,考虑同步的话,可以使用this来充当锁。但是在继承的方法中,慎用this
 *         
 *         方式二:同步方法    
 *         将操作共享数据的方法声明为synchronized。即此方法为同步方法,能够保证当其中一个线程执行此方法时,
 *         其他线程在外等待直至此线程执行完此方法。
 * 
 * @author hasee
 *
 */

//实现的方式
//加锁实现同步(同步代码块)
class Window1 implements Runnable {
    int ticket = 100;

    Object obj = new Object();

    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ":" + ticket--);
                } else {
                    break;
                }
            }
        }
    }
}

//实现的方式(通过静态共享变量保证多个线程修改的是同一个变量)
class Window2 implements Runnable {
    static int ticket = 100;

    public void run() {
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.currentThread().sleep(10); //将多线程的错误放大
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + ticket--);
            } else {
                break;
            }
        }
    }
}

//同步的方式(通过继承的方式来实现多线程)
class Window3 extends Thread {
    static int ticket = 100;
    static Object obj = new Object();    //静态的监视器,避免不同进程使用不同的监视器,造成无法同步的安全问题
    public void run(){
        while(true){
            synchronized (obj) {
                if(ticket > 0){
                    try {
                        Thread.currentThread().sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + ticket--);
                }
            }
            
        }
    }
}

//同步的方法(通过接口实现)
class Window4 implements Runnable {
    int ticket = 100;    //共享数据

    public void run() {
        while (true) {
            show();
        }
    }
    
    //将该方法声明为synchronized方法
    public synchronized void show(){
        if (ticket > 0) {
            try {
                Thread.currentThread().sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" + ticket--);
        }
    }
}

public class TestWindow1 {
    public static void main(String[] args) {
        // 方式一:3个Thread共享一个Window1类对象
        Window1 w = new Window1();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
        t1.start();
        t2.start();
        t3.start();

        // 方式二:三个Window2类对象,各自分别对应了3个Thread
        // 这种方式必须保证共享的变量(即共享资源)为静态的,否则出错
        // Window2 w21 = new Window2();
        // Window2 w22 = new Window2();
        // Window2 w23 = new Window2();
        // Thread t21 = new Thread(w21);
        // Thread t22 = new Thread(w22);
        // Thread t23 = new Thread(w23);
        // t21.start();
        // t22.start();
        // t23.start();

    }
}

15 - 工具方法一般都声明为static方法

原文地址:https://www.cnblogs.com/zishu/p/10414094.html