Java基础

2018-10-14  本文已影响0人  Vanes丶

Java体系架构

JavaSE : Java Standard Edition
JavaEE : Java Enterprise Edition
JavaME : Java Micro Edition

Java语言的特点

Java跨平台的原理

JVM Java虚拟机

image

垃圾回收器

JavaSE 的组成概念图

[图片上传失败...(image-ef41d0-1539494346308)]

数组内存结构分析

存储确定大小的数据类型:临时变量,基本数据类型,引用类型。由于固定大小,所以存取速度较快。

存储不确定大小的值(譬如值可能发生改变),需要临时地动态地进行分配,速度相对于栈较慢。

    譬如:  
    String[] name = {"AA","bb","CC"};
    name 这个数组名会在栈内存中开辟空间,name 对应的是数组的地址
    而 name 数组所对应的值则会在堆内存中开辟空间

多维数组

    int[] array = new int[3];
    int newlen = array.length*3/2 + 1;
    array = Arrays.copyOf(array,newlen);

对象与内存分析

new 关键字深入

对象内存分析

class Dog{
    String name;
    int age;
}

构造方法

Type name = new Type();

此时的 Type() 其实就是调用了相应的构造方法。

方法重载 ovrloading method

匿名对象

class Dog{
    private String name;
    private int age;
    public say();
}

// 该对象只能使用一次
new Dog().say();

值传递与引用传递


int x = 10;
method(x);
System.out.println("x="+x);//10

public static void method(int mx){
    mx = 20;
}

Cat c = new Cat();
method(c);
System.out.println("Cat age = " + c.age);//5

public static void method(Cat cat){
    cat.age = 5;
}

class Cat{
    int age = 2;
}

String name = "小白";
method(name);
System.out.println(name);//小白

public static void method(String sname){
    sname = "小红";
}


Cat c = new Cat();
method(c);
System.out.println("Cat name = " + c.name);

public static void method(Cat cat){
    cat.name = "小黑";
}

class Cat{
    String name = "小白";
}

- 执行method()后

[图片上传失败...(image-bafc4e-1539494346308)]

static关键字

[图片上传失败...(image-a00880-1539494346308)]

本质:static关键字修饰的属性和方法都是属于类的,并不属于对象,所以static修饰的属性和方法实在对象之前进行创建和加载的,故不能调用和访问属于对象的相关属性(非static修饰的属性和方法)。最好是使用类直接去调用static方法,虽然对象也可以调用static方法,但是static是属于类的

main方法

对象数组

foreach 与可变参数 jdk1.5

for(类型变量名称:数组或集合){
    //输出操作
}
返回值类型 方法名称(数据类型...参数名称){
    //同一个类型的参数传入,数量可变
    //但如果有其他类型的参数,需要将可变参数放在最末
}

代码块

直接写在方法中的代码块就是普通代码块

构造块是在类中定义的代码块,在构造对象时调用,先于构造方法执行

在类中使用static声明的构造块就是静态块,先于构造块执行。因为静态块是属于类的,而不属于对象,所以在加载的时候最先执行的是静态块。在类加载时执行,只执行一次

public class Demo{

    //构造块
    {
        String str = "构造块";
        System.out.println(str);//此时无法输出,只有在new之后即构造之后才会执行
    }
    
    public Demo(){
        System.out.println("我是构造方法");
    }
  
    //静态块  
    static{
        System.out.println("我是静态块");
    }


    public static void main(String[] args){
    
        Code code1 = new Code();
        Code code2 = new Code();
    
    
        // 普通代码块
        {
            String str ="abc";
            System.out.println(str);
        }
    }
}

单例设计模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  1. 构造方法私有化
  2. 声明一个本类对象
  3. 给外部提供一个静态方法获取对象实例
  1. 饿汉式 先生成对象(从一开始就创建对象)
  2. 懒汉式 后生成对象(需要用到的时候才创建对象,涉及到多线程安全问题,需要改进)
public static void main(String[] args) {
    Singleton1 singleton1 = Singleton1.getInstance();
    singleton1.print();
    Singleton1 singleton12 = Singleton1.getInstance();
        System.out.println(singleton1 == singleton12);//因为是同一个对象,输出为true
        
    Singleton2 singleton2 = Singleton2.getInstance();
    singleton2.print();
    }


/**
 * 单例设计模式
 * 饿汉式  
 */
class Singleton1{
    
    // 定义一个对象并实例化
    private static Singleton1 singleton1 = new Singleton1();
    
    // 构造方法私有化
    private Singleton1(){
        
    }
    
    // 获取实例 的静态方法
    public static Singleton1 getInstance(){
        return singleton1;
    }
    
    public void print(){
        System.out.println("饿汉式-单例设计模式");
    }
}

/**
 * 单例设计模式
 * 懒汉式(多线程访问时会有安全问题)
 */
class Singleton2{
    
    // 定义一个对象并实例化
    private static Singleton2 singleton2 = null;
    
    // 构造方法私有化
    private Singleton2(){
        
    }
    
    // 获取实例 的静态方法
    public static Singleton2 getInstance(){
        if(singleton2 == null){
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
    
    public void print(){
        System.out.println("懒汉式-单例设计模式");
    }
}

继承

子类的实例化过程

方法的重写

子类不想原封不动地继承父类的方法时,即想对从父类出继承来的方法进行一些自定义地改写,这就需要方法的重写,也称为方法的覆盖

super关键字

final关键字

抽象类

很多具有相同特征和行为的对象可以抽象为一个类;很多具有相同特征和行为的类可以抽象成一个抽象类。使用abstract关键字声明

接口

接口是一组行为的规范、定义、没有实现
面向对象设计法则:基于接口编程

interface 接口名称{
    全局常量;
    抽象方法;
}

多态

对象多态性是从继承关系中的多个类而来

//char的容量比int小,所以可以自动完成
int i = 'a';

父类 父类对象 = 子类实例;//自动转换
Person man = new Man();//父类的引用执行子类对象
Person woman = new Woman();

子类 子类对象 = (子类)父类实例; 强制转换
Man m = (Man)man;//强制转换
Man m1 = (Man)woman;//报类型转换异常,转换失败

//整形(4个字节)比char(2个字节)要大,所以需要强制转换
char c = (char) 97;

强制转换

在Java中强制类型转换分为基本数据类型和引用数据类型两种

instanceof关键字

格式:对象 instanceof 类型 返回 booleann类型值

package com.review;
public class InstanceofKeyWordDemo {
    public static void main(String[] args) {
        Person man = new Man();
        say((Man)man);//父类对象需要强制转换为子类对象
        
        Woman woman = new Woman();
        say(woman);
    }
    
//  //static 和 返回类型 的位置不可交换
//  public static void say(Man man){
//      man.say();
//  }
//  
//  public static void say(Woman woman){
//      woman.say();
//  }
    
    public static void say(Person person){
        person.say();
//      person.getAngry(); //由于父类没有该方法,故无法调用
//      Woman woman = (Woman)person; //会报出类型转换异常,因为传入的person可能为man
        
        // 判断person对象是否为woman的实例
        if(person instanceof Woman){
            Woman woman = (Woman)person;
            woman.getAngry();
        }
        
    }
}

abstract class Person{
    private String name;
    public void setName(String name){
        this.name = name;
    }
    
    public String getName(){
        return name;
    }
    
    public abstract void say();//抽象方法
}

class Man extends Person{
    @Override
    public void say() {
        // TODO Auto-generated method stub
        System.out.println("I am a man!!!");
    }
}

class Woman extends Person{
    @Override
    public void say() {
        // TODO Auto-generated method stub
        System.out.println("I am a woman!!!!");
    }
    
    // 本类中进行扩展的方法
    public void getAngry(){
        System.out.println("I am angry!!!");
    }
    
}

抽象类应用

定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤。

接口应用

定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。

OO设计原则:

Object类

[图片上传失败...(image-fd69-1539494346308)]

//Object 类的 toString 方法返回一个字符串
//该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
public boolean equals(Object obj) {
        return (this == obj);
    }

equals
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系:

  • 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
  • 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 > true。
  • 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
  • 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
    对于任何非空引用值 x,x.equals(null) 都应返回 false。
    Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 >y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。
另请参见:
hashCode(), Hashtable

简单工厂模式

简单工厂模式是由一个公告对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。

/**
 * 工厂设计模式:
 * 
 */
public class FactoryDemo {
    
    public static void main(String[] args) {
        
//      ClothDoll clothDoll = new ClothDoll();
//      System.out.println(clothDoll.getInfo());
//      
//      BarbieDoll barbieDoll = new BarbieDoll();
//      System.out.println(barbieDoll.getInfo());
        
        Doll clothDoll = DollFactory.getInstance("ClothDoll");
        if(null != clothDoll)
            System.out.println(clothDoll.getInfo());
        Doll barbieDoll = DollFactory.getInstance("Barbie");
        if(null != barbieDoll)
            System.out.println(barbieDoll.getInfo());
    }
}

//工厂类  降低耦合性(主函数与具体类之间的耦合)  解耦合     转移依赖关系
/**
 * 避免主类直接调用具体类来定义对象,然而被调用类可能发生了一些改变,
 * 那么对于main类的代码将会产生影响,可维护性下降,因为太过于依赖具体的类,
 * 故想让主类不与具体类产生依赖关系,所以选择引入工厂模式,也就是一个中间类,
 * 中间类中根据条件产生相应的对象,依赖具体的类,而主类只是需要调用工程类的
 * 相应方法并传入不同的参数就可以产生相应的对象。
 */
class DollFactory{
    public static Doll getInstance(String name){
        // 根据条件生产不同的对象
        if("ClothDoll".equals(name)){
            return new ClothDoll();
        }else if("Barbie".equals(name)){
            return new BarbieDoll();
        }else{
            return null;
        }
    }
    
}


interface Doll{
    String getInfo();
}

class ClothDoll implements Doll{
    public String getInfo(){
        return "我是布娃娃,我怕脏";
    }
}

class BarbieDoll implements Doll{
    public String getInfo(){
        return "我是芭比娃娃,我美得不可思议";
    }
}

静态代理模式

把很多对象都具有的相同动作抽象出来,创建一个代理类。

/**
 * 代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的访问
 */
public class ProxyDemo {

    public static void main(String[] args) {
        MiaiPerson person = new MiaiPerson("小白");
        
        //创建代理对象
        Matchmaker matchmaker = new Matchmaker(person);
        matchmaker.miai();
    }
    
}

/**
 * 主题接口
 */
interface Subject{
    public void miai();
}

/**
 * 被代理的类
 */
class MiaiPerson implements Subject{
    private String name;
    public MiaiPerson(String name){
        this.name = name;
    }
    
    public void miai(){
        System.out.println(name+"正在相亲中...");
    }
}

/**
 * 代理类
 */
class Matchmaker implements Subject{
    private Subject target;//要代理的目标对象
    
    public Matchmaker(Subject target){
        this.target = target;
    }
    
    public void before(){
        System.out.println("为代理人匹配如意郎君。");
    }
    
    public void after(){
        System.out.println("本次相亲结束");
    }
    
    @Override
    public void miai() {
        before();
        // 真正执行相亲的方法
        target.miai();
        after();
    }
    
    
}

适配器模式

将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

OO设计原则:

  • 面向接口编程
  • 封装变化
  • 多用组合少用继承
  • 对修改关闭,对扩展开放
public class AdapterDemo {
    
    public static void main(String[] args) {
        PowerA powerA = new PowerAImplA();
        startA(powerA);
        
        
        PowerB powerB = new PowerBImpl();
        //startA(powerB); 报错
        PowerAAdapter pAAdapter = new PowerAAdapter(powerB);
        startA(pAAdapter);
        
    }
    
    public static void startA(PowerA powerA){
        // ......
        powerA.insert();
        // ......
    }
    //与startA的内容大部分重复
//  public static void startB(PowerB powerB){
//      // ......
//      powerB.connect();
//      // ......
//  }
}

class PowerAAdapter implements PowerA{
    
    private PowerB powerB;// 要进行适配的接口
    
    public PowerAAdapter(PowerB powerB) {
        this.powerB = powerB;
    }

    @Override
    public void insert() {
        powerB.connect();
    }
    
}

/**
 * 电源A接口
 */
interface PowerA{
    public void insert();
}

class PowerAImplA implements PowerA{

    @Override
    public void insert() {
        // TODO Auto-generated method stub
        System.out.println("电源A接口插入,开始工作。");
    }
    
}

/**
 * 电源B接口
 */
interface PowerB{
    public void connect();
}

class PowerBImpl implements PowerB{
    public void connect(){
        System.out.println("电源B接口已连接。");
    }
}

内部类

内部类的基本概念

在一个类的内部定义的类

class Outer{
    class Inner{
        
    }
}

在外部创建内部类对象

Outer out = new Outer();//产生外部类实例
Outer.Inner in = null;//声明内部类对象
in = out.new Inner();//实例化内部类对象

方法内部类

class Outer{
    public void doSomething(){
        class Inner{
            public void seeOuter(){
                
            }
        }
    }
}
public class InnerClassDemo1 {
    
    public static void main(String[] args) {
        Dog dog = new Dog("二妞");
        dog.say();
        Dog.ChildDog childDog = null;//声明内部类引用
        
        // 该方式一般不使用
        childDog = dog.new ChildDog();//创建内部类的实例
        childDog.talk();
        
        dog.childTalk();
        
    }

}

class Dog{
    private String name;
    public Dog(String name){
        this.name = name;
    }
    public void say(){
        System.out.println("我是一只狗,主人叫我" + name);
    }
    //内部类(成员内部类)
    class ChildDog{
        public void talk(){
            System.out.println("我是一只小狗狗,我妈是" + name);
        }
    }
    
    public void childTalk(){
        ChildDog childDog = new ChildDog();
        childDog.talk();
    }
}

public class InnerClassDemo2 {

}

class Dog{
    private String name;
    public Dog(String name){
        this.name = name;
    }
    public void say(){
        System.out.println("我是一只狗,主人叫我" + name);
    }
    
    // 在方法里面声明一个内部类
    public void childTalk(final String childName){
        final int x = 10;
        class ChildDog{
            public void talk(){
                System.out.println("我是一只狗狗,我妈妈是"+ name);
                System.out.println("x=" + x);
                System.out.println("我的名字是" + childName);
            }
        }
        ChildDog childDog = new ChildDog();
        childDog.talk();
    }
}

静态内部类

class Outer{
    static class Inner{}
}
class Test{
    public static void main(String[] args){
        
    }
}

匿名内部类

匿名内部类就是没有名字的内部类

public class InnerClassDemo4 {

    public static void main(String[] args) {
        // 1、继承式匿名内部类
        Dog dog = new Dog("小白"){
            public void say(){
                System.out.println("我是一只womanDog");
            }
        };
        dog.say();
        
        // 2.接口式匿名内部类
        Child child = new Child() {
            
            @Override
            public void talk() {
                // TODO Auto-generated method stub
                System.out.println("我是一只小狗狗");
            }
        };
        child.talk();
    
    
        // 3、参数式匿名内部类
        childTalk(new Child() {
            
            @Override
            public void talk() {
                // TODO Auto-generated method stub
                System.out.println("我是一只小狗狗");
            }
        });
    
    }
    
    
    public static void childTalk(Child child){
        child.talk();
    }
}

class Dog{
    private String name;
    public Dog(String name){
        this.name = name;
    }
    public void say(){
        System.out.println("我是一只狗,主人叫我" + name);
    }
}

class WomanDog extends Dog{
    public WomanDog(String name){
        super(name);
    }
    public void say(){
        System.out.println("我是一只womanDog");
    }
}

interface Child{
    public void talk();
}

内部类的作用

上一篇 下一篇

猜你喜欢

热点阅读