一、内存解析
public class Birthday {
private int day;
private int month;
private int year;
public Birthday(int d,int m,int y){
day = d;
month = m;
year = y;
}
public void setDay(int d){
this.day = d;
}
public void setMonth(int m){
this.month = m;
}
public void setYear(int y){
this.year = y;
}
public int getDay(){return this.day;}
public int getMonth(){return this.month;}
public int getYear(){return this.year;}
public void display(){
System.out.println(day + "-" + month + "-"+year);
}
}
public class Test {
public static void main(String[] args) {
//存放在堆中
//栈中d1,d2指针指向该数据堆的地址
Birthday d1 = new Birthday(7, 7, 1970);
Birthday d2 = new Birthday(1, 1, 2000);
//存放在堆内存中,栈中指针指向堆的地址
Test test = new Test();
//在栈中
int date = 9;
test.change1(date);
System.out.println("date = " + date);
// d1是birthday的一个引用
test.change2(d1);
d1.display();
test.change3(d2);
d2.display();
}
/**
*
* @param i 形参,在栈内存中存放 i = 9
* 形参是值传递!!!
*/
public void change1(int i){
i = 1234;
}
/**
*
* @param b引用和d1都是指向同一块堆地址
* 栈中的内存,程序调用之后就会消失
* b在堆中,由gc处理
*/
public void change2(Birthday b){
b = new Birthday(22,2,2004);
}
public void change3(Birthday b){
//真真正正改变了堆中数据的值!!!
b.setDay(20);
}
}
二、方法的重载
定义:相同函数名,相同返回值,参数个数、类型不一样
public class Test {
void max(int a,int b){
System.out.println(a > b ? a : b);
}
/**
* 返回值不同不构成重载,编译器解析有争议
* 如果调用test.max(1,2),有争议
*/
//int max(int a,int b){
// System.out.println(a > b ? a : b);
//}
void max(float a,float b){
System.out.println(a > b ? a : b);
}
public static void main(String[] args) {
Test test = new Test();
test.max(1,2);
test.max(1.0f,2.0f);
}
}
public class Test {
void max(int a,int b){
System.out.println(a > b ? a : b);
}
/**
* 返回值不同不构成重载,编译器解析有争议
* 如果调用test.max(1,2),有争议
*/
//int max(int a,int b){
// System.out.println(a > b ? a : b);
//}
void max(float a,float b){
System.out.println(a > b ? a : b);
}
public static void main(String[] args) {
Test test = new Test();
test.max(1,2);
test.max(1.0f,2.0f);
}
}
对象的创建和使用
- 必须使用new关键字创建对象
- 使用对象引用.成员变量
- 使用 对象引用.方法 来调用对象的方法
- 同一类的每个对象有不同的成员变量存储空间
- 同一类的每个对象共享该类的方法
- 非静态方法是针对每个对象进行调用
三、this关键字
this可以看做是一个变量,他的值是当前对象的引用
public class Leaf {
//成员变量
int i = 0;
Leaf(){
}
Leaf(int i){
this.i = i;
}
Leaf increament(){
i++;
return this; //仍指向当前对象
}
void print(){
System.out.println("i = " + i);
}
public static void main(String[] args) {
Leaf leaf = new Leaf(100);
leaf.increament().increament().print();
Leaf leaf1 = new Leaf();
leaf1.print();
}
}
四、static 关键字
静态成员变量,它为该类的公共变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份
用static声明的方法为静态方法,调用该方法时,不会将对象的引用传递给他,所以在static方法中不可以访问非static的成员
静态方法不针对某个对象调用,所以不能访问非静态成员
可以通过对象引用或者类名(不需要实例化)访问静态成员
静态变量在数据区!!!
public class Cat {
private static int sid = 0;
private String name;
int id;
Cat(String name){
this.name = name;
id = sid++;
}
public void info(){
System.out.println("My name is " + name + " No. " + id);
}
public static void main(String[] args) {
Cat.sid = 100;
Cat mimi = new Cat("mimi");
Cat pipi = new Cat("pipi");
mimi.info();
pipi.info();
}
}
五、package和import语句
包:解决类名的冲突问题
package语句是java源文件的第一条语句,指明该文件中定义的类所在的包
访问同一个包中的类不需要引入
必须calss文件的最上层包的父目录位于classpath下?
…
六、继承与权限控制
对于class的权限修饰只可以用 public 和 default
- public类可以在任意地方被访问
- default类只可以被同一个包内部的类访问
class Person {
//不能被继承
private String name;
private int age;
//public protected 子类可以访问
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
class Student extends Person{
private String school;
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school = school;
}
public void info(){
this.setName("kcl");
System.out.println(this.getName());
}
}
public class Test{
public static void main(String[] args) {
Student student = new Student();
student.info();
student.setName("John");
}
}
public class TestAccess {
}
class T{
private int i = 0;
int j = 0;
protected int k = 0;
public int m = 0;
}
class TT{
public void m(){
T t = new T();
//同一包下的其他类可以访问
//不同包下不能访问
System.out.println(t.j);
}
}
七、方法的重写
在子类中可以根据需要对从基类继承的方法进行重写
重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型
重写方法不能使用比被重写方法更严格的访问权限
父类继承的方法不满意
public class Test {
public static void main(String[] args) {
Student student = new Student();
Person person = new Person();
person.setName("none");
person.setAge(100);
student.setName("John");
student.setAge(18);
student.setSchool("USTC");
System.out.println(person.getInfo());
System.out.println(student.getInfo());
}
}
class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public String getInfo(){
return "Name: " + name + "\n" + "age: " + age;
}
}
class Student extends Person{
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String getInfo() {
return "Name: " + this.getName() + "\n" + "age: " + this.getAge()
+ " school " + this.getSchool();
}
}
八、super关键字
public class TestInherit {
public static void main(String[] args) {
ChildClass childClass = new ChildClass();
childClass.f();
}
}
class FatherClass{
//默认为0
public int value;
public void f(){
System.out.println("FatherClass.value="+value);
}
}
class ChildClass extends FatherClass{
public int value;
public void f(){
//调用父类方法
super.f();
//调用本类value
value = 200;
System.out.println("ChildClass.value="+value); // 0
System.out.println(value); // 200
super.value = 300;
System.out.println(super.value); //300
}
}
子类构造方法必须调用父类的构造方法
super关键字写在子类构造函数的第一行
如果子类的构造方法中没有显示地调用基类构造方法,则系统默认调用基类无参的构造方法
不写任何构造函数,编译器会自动加上一个无参构造方法
如果写了一个构造方法,那么编译器不会自动加上无参构造方法
子类的构造方法中必须调用super父类的构造方法,如果不写super,系统默认调用父类无参构造方法!!!
若父类没有无参构造函数,子类构造方法又没有调用super方法,则编译器会报错!!!
九、Object类的toString()方法
System.out.lprintln(“info”+person),自动调用该对象类的toString方法
public class TestToString {
public static void main(String[] args) {
Dog dog = new Dog();
//com.kcl.g_toString.Dog@3930015a
//return getClass().getName() + "@" + Integer.toHexString(hashCode());
System.out.println(dog);
//相当于
//推荐所有类重写toString方法
System.out.println(dog.toString());
//959447386
System.out.println(dog.hashCode());
//class com.kcl.g_toString.Dog
System.out.println(dog.getClass());
}
}
// "根类"默认继承Object类
class Dog {
}
十、hashcode
十一、equals方法
public class TestEquals{
public static void main(String args[]){
Cat c1 = new Cat(1,2,3);
Cat c2 = new Cat(1,2,3);
// false
System.out.println(c1.equals(c2));
}
}
class Cat{
int color;
int height,weight;
public Cat(int color,int height,int weight){
this.color = color;
this.height = height;
this.weight = weight;
}
}
十二、多态
/**
* 动态绑定是值在执行期间,非编译期间,判断所引用对象的实际类型,根据其实际的类型调用相应的方法
*/
class Animal{
private String name;
Animal(String name){
this.name = name;
}
public void enjoy(){
System.out.println("叫声......");
}
}
class Cat extends Animal{
private String eyesColor;
Cat(String n,String c){
super(n);
this.eyesColor = c;
}
@Override
public void enjoy() {
System.out.println("猫叫声......");
}
}
class Dog extends Animal {
private String furColor;
Dog(String n, String c) {
super(n);
this.furColor = c;
}
@Override
public void enjoy() {
System.out.println("狗叫声......");
}
}
class Lady{
private String name;
private Animal pet;
Lady(String name,Animal pet){
this.name = name;
this.pet = pet;
}
public void myPetEnjoy(){
pet.enjoy();
}
}
public class Test {
public static void main(String[] args) {
Cat c = new Cat("catname", "blue");
Dog d = new Dog("dogname", "black");
Lady l1 = new Lady("l1", c);
Lady l2 = new Lady("l2", d);
l1.myPetEnjoy();
l2.myPetEnjoy();
}
}
代码段
根据Lady对象的成员变量pet所引用的不同的实际类型而调用响应的enjoy方法
3个必要条件
- 要有继承
- 要有重写
- 父类引用指向子类对象
当你调用父类里面被重写的方法时,实际当中new的哪个子类对象,就调用哪个子类对象的方法
十三、抽象类
- 用abstract关键字修饰的类叫抽象类,用abstract修饰的方法 就做抽象方法。
- 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写!
- 抽象类不能被实例化
- 抽象方法只需声明,不能实现
abstract class Animal{
private String name;
Animal(String name){
this.name = name;
}
//每种具体动物有自己的高兴方式!!,相当于c++的纯虚函数
//抽象方法就是用来重写的
public abstract void enjoy();
}
class Cat extends Animal{
private String eyesColor;
//继承必须实现super,调用父类的构造方法
Cat(String name,String c) {
super(name);
this.eyesColor = c;
}
//必须实现抽象类的所有抽象方法
@Override
public void enjoy() {
System.out.println("猫叫声");
}
}
十四、final关键字
- final的方法不能被重写
- final的类不能被继承
- final的变量不能被改变(final成员变量、final局部变量)
public class Test {
public static void main(String[] args) {
T t = new T();
System.out.println(t.i);
}
}
final class T{
public final int i = 8;
public void m(final int j){
// 在方法中不能改变,只读不能写
//j = 9;
}
}
// final类不能被继承
//class TT extends T{
//}
final不想被别人继承
abstract就是想给人继承
十五、interface 接口
-
多个无关的类可以实现同一个接口
-
一个类可以实现多个无关的接口
-
与继承关系类似,接口与实现类之间存在多态性
-
接口interface是抽象方法和常量值的定义的集合
-
本质上来说,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的
定义而没有变量和方法的实现
接口中声明的成员变量属性默认为public static final的;也只能是 public static final的
接口中只能定义抽象方法,而且这些方法默认为public abstract的、也只能是public abstract的
接口可以继承其他接口,并添加新的属性和抽象方法
public class Test {
public static void main(String[] args) {
//接口和实现类之间存在多态性,类似于继承
Singer s1 = new Student("le");
s1.sing();
s1.sleep();
// s2是teacher对象,把他当成singer来看
Singer s2 = new Teacher("steven");
s2.sing();
s2.sleep();
//类似于多态
//把s2当做painter来看
Painter p1 = (Painter) s2;
p1.paint();
p1.eat();
}
}
interface Singer{
void sing();
public abstract void sleep();
}
interface Painter{
void paint();
void eat();
}
// student 能唱歌
class Student implements Singer{
private String name;
Student(String name){
this.name = name;
}
@Override
public void sing() {
System.out.println("student is singing");
}
@Override
public void sleep() {
System.out.println("student is sleeping");
}
}
class Teacher implements Singer,Painter{
private String name;
Teacher(String name){
this.name = name;
}
@Override
public void sing() {
System.out.println("teacher is singing");
}
@Override
public void sleep() {
System.out.println("teacher is sleeping");
}
@Override
public void paint() {
System.out.println("teacher is painting");
}
@Override
public void eat() {
System.out.println("teacher is eating");
}
}
十六、一维数组
Java数组存放在堆中,C++可以存放在栈中。
数组必须先分配空间后,才可以装值
十七、二维数组
public class Test {
public static void main(String[] args) {
// 先分配第一维
int [][] a = new int[3][];
// 再分配第二维
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];
}
}
public class Test {
public static void main(String[] args) {
int [][] a = {{1,2},{3,4,5,6},{7,8,9}};
for(int i = 0; i < a.length; i++){
for(int j = 0; j < a[i].length; j++){
System.out.print(a[i][j] + " ");
}
System.out.println();
}
}
}
十八、String
public class Test {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "hello";
//编译器优化,同一个指向
System.out.println(s1 == s3); //true
s1 = new String("hello");
s2 = new String("hello");
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2); //true
char c[] = {'s','u','n',' ','j','a','v','a'};
String s4 = new String(c);
String s5 = new String(c,4,4);
System.out.println(s4); // sun java
System.out.println(s5); // java
}
}
解析:
public class Test {
public static void main(String[] args) {
Person p1 = new Person(1);
Person p2 = new Person(2);
Person p3 = p1;
System.out.println(p1 == p2); //false
System.out.println(p3 == p1);//true
System.out.println(p1.equals(p2)); // false
System.out.println(p1.equals(p3)); // true
// public boolean equals(Object obj) {
// return (this == obj);
// }
}
}
class Person{
int id;
public Person(int id){
this.id = id;
}
}
public class Test {
public static void main(String[] args) {
String s1 = "sun java",s2 = "Sun Java";
System.out.println(s1.charAt(1)); // u
System.out.println(s2.length()); // 8
System.out.println(s1.indexOf("java")); //4
System.out.println(s1.indexOf("Java")); //-1
System.out.println(s1.equals(s2)); // false
System.out.println(s1.equalsIgnoreCase(s2)); //true
String s = "我是程序员,我在学习java";
String str = s.replace('我','你');
System.out.println(str); //你是程序员,你在学习java
}
}
public class Test {
public static void main(String[] args) {
String s = "Welcome to Java World!";
String s1 = " sun java ";
System.out.println(s.startsWith("Welcome"));//true
System.out.println(s.endsWith("World"));//false
System.out.println(s.toLowerCase());//welcome to java world!
System.out.println(s.toUpperCase());//WELCOME TO JAVA WORLD!
System.out.println(s.substring(11));//Java World!
System.out.println(s1.trim());//sun java
}
}
十九、 String Split
public static void main(String[] args) {
int j = 1234567;
String number = String.valueOf(j);
System.out.println("j 是" + number.length() + "位数. ");
String s = "Mary,F,1976";
String[] split = s.split(",");
for(String t : split){
System.out.println(t);
}
}
二十、 StringBuffer类
StringBuffer()
创建一个不包含字符序列的“空”的StringBuffer对象
StringBuffer(String str)
创建一个StringBuffer对象,包含与String对象str相同的字符序列
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
s1 += s2;
}
append()
方法调用后仍然返回当前字符串的引用
public static void main(String[] args) {
String s = "Mircosoft";
char[] a = {'a','b','c'};
StringBuffer sb1 = new StringBuffer(s);
sb1.append('/').append("IBM")
.append('/').append("Sun");
System.out.println(sb1); //Mircosoft/IBM/Sun
StringBuffer sb2 = new StringBuffer("数字");
for(int i = 0; i <= 9; i++){
sb2.append(i);
}
System.out.println(sb2); //数字0123456789
sb2.delete(8,sb2.length()).insert(0,a);
System.out.println(sb2); //abc数字012345
System.out.println(sb2.reverse()); //543210字数cba
}
```
# 二十一、基本数据类型包装类


```java
public static void main(String[] args) {
long a = 1024;
String s = Long.toBinaryString(a);
System.out.println(s); //10000000000
String s2 = Integer.toBinaryString(234);
System.out.println(s2); //11101010
Long a2 = new Long(a);
double v = a2.doubleValue();
System.out.println(v); //1024.0
}
public static void main(String[] args) {
Integer i = new Integer(100); //分配在堆空间内
Double d = new Double("123.456");
int j = i.intValue() + d.intValue();
float f = i.floatValue() + d.floatValue();
System.out.println(j); // 223
System.out.println(f); //223.456
System.out.println(Long.MAX_VALUE);
double pi = Double.parseDouble("3.1415926");
double r = Double.valueOf("2.0").doubleValue();
double s = pi*r*r;
System.out.println(s); //12.5663704
try{
int k = Integer.parseInt("1.25"); //转不了
}catch (NumberFormatException e){
System.out.println("数据格式不对!");
}
System.out.println(Integer.toBinaryString(123)+"B"); //1111011B
System.out.println(Integer.toHexString(123)+"H"); //7bH
System.out.println(Integer.toOctalString(123)+"O"); //173O
}
二十二、Math类
二十三、Enum枚举类型
- 只能取特定值中的一个
- 使用enum关键字
- 是java.lang.Enum类型
//定义枚举类型
//然后用类型定义变量
public enum MyColor {
red,
green,
blue
};
public static void main(String[] args) {
//类似静态变量
MyColor m = MyColor.red;
switch (m){
case red:
System.out.println("red");
break;
case green:
System.out.println("green");
break;
default:
System.out.println("default");
}
System.out.println(m); //red
}
二十四、Collection容器
- map是一对一对往里装,左边的都是一个一个往里装
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("hello");
c.add(new Integer(100));
System.out.println(c.size()); //2
System.out.println(c); //[hello, 100]
}
public class Test {
public static void main(String[] args) {
Collection c = new HashSet();
c.add("hello");
c.add(new Name("f1","l1"));
c.add(100);
c.remove("hello");
c.remove(100);
System.out.println(c); //[f1 l1]
System.out.println(c.remove(new Name("f1","l1"))); //false
}
}
class Name{
private String firstName,lastName;
public Name(String firstName,String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public String toString(){
return firstName + " " + lastName;
}
}
重写equals() 方法一定要重写hashCode()方法
系统先找hashCode判断是否相等,然后判断equals方法!!!
public class Test {
public static void main(String[] args) {
Collection c = new HashSet();
c.add(new Name("f1","l1"));
System.out.println(c); //[f1 l1]
System.out.println(c.remove(new Name("f1","l1"))); //true
}
}
class Name{
private String firstName,lastName;
public Name(String firstName,String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String toString(){
return firstName + " " + lastName;
}
public boolean equals(Object obj){
if(obj instanceof Name){
Name name = (Name)obj;
return (firstName.equals(name.firstName)) && (lastName.equals(name.lastName));
}
return super.equals(obj);
}
//一般使用equals方法判断两个对象是否相等
//当类作为map使用时,需要用到hashCode方法,因为这样效率更高
//两个对象如果相等,那么hashCode值相等
public int hashCode(){
return firstName.hashCode();
}
}
二十五、Iterator接口
接口的继承
有继承
有重写方法
父类引用指向子类对象
暴露这三个方法即可
public static void main(String[] args) {
Collection c = new LinkedList();
c.add("kcl");
c.add("super");
c.add("ustc");
// LinkedList提供的遍历自身的iterator对象
Iterator iterator = c.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
二十六、List接口
List l1 = new LinkedList<>();
for(int i = 0; i <= 5; i++) l1.add("a"+i);
System.out.println(l1); //[a0, a1, a2, a3, a4, a5]
l1.add(3,"a100");
System.out.println(l1);//[a0, a1, a2, a100, a3, a4, a5]
l1.set(6,"a200");
System.out.println(l1);//[a0, a1, a2, a100, a3, a4, a200]
String s =(String) l1.get(2);
System.out.println(s); //a2
System.out.println(l1.indexOf("a3")); //4
l1.remove(1);
System.out.println(l1);//[a0, a2, a100, a3, a4, a200]
public static void main(String[] args) {
List l1 = new LinkedList();
List l2 = new LinkedList();
for(int i = 0; i < 10; i++) l1.add(i);
//随机排列
Collections.shuffle(l1);
System.out.println(l1);//[9, 0, 6, 2, 3, 5, 8, 4, 7, 1]
//逆序
Collections.reverse(l1);
System.out.println(l1);//[1, 7, 4, 8, 5, 3, 2, 6, 0, 9]
//正序排列
Collections.sort(l1);
System.out.println(l1);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//二分查找
System.out.println(Collections.binarySearch(l1,5));//5
}
二十七、Comparable接口
public class Test {
public static void main(String[] args) {
Person p1 = new Person("张三", 18, 1);
Person p2 = new Person("李四", 16, 2);
Person p3 = new Person("王二麻", 22, 3);
List list = new LinkedList();
list.add(p1);
list.add(p2);
list.add(p3);
Collections.sort(list);
System.out.println(list);
}
}
class Person implements Comparable{
private String name;
private int age;
private int id;
public Integer getAge() {
return age;
}
public Person(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
@Override
public int compareTo(Object o) {
Person p2 = (Person) o;
if(p2.getAge() == this.getAge()) return 0;
//向后排,返回正数,向前排,返回负数
if(this.getAge() > p2.getAge()) return 1;
else return -1;
}
}
这里Comparable参数为null
调用归并排序?
根据对象的CompareTo方法进行比较
二十八、Map
public static void main(String[] args) {
Map m1 = new HashMap();
Map m2 = new TreeMap();
m1.put("one",1);
m1.put("two",2);
m1.put("three",3);
m2.put("A",1);
m2.put("B",2);
System.out.println(m1.size()); //3
System.out.println(m1.containsKey("one")); //true
System.out.println(m2.containsValue(2));//true
Map m3 = new HashMap(m1);
m3.putAll(m2);
System.out.println(m3);//{A=1, B=2, two=2, three=3, one=1}
}