静态访问非静态 ,非静态必须实例化
1.内部类
分为四种形式:
①成员内部类;
②静态内部类static;
③局部内部类:定义在方法内部;
④匿名内部类:无名内部类,比如在某个方法下面不命名new一个对象;
概念:在一个类的内部再定义一个类
特点:编译后可生成独立的字节码文件 :)见下方图
内部类可以直接访问外部类的私有成员,而不破坏封装
可以为外部类提供必要的内部功能组件
①成员内部类;
在类的内部定义,与实例变量、实例方法同级别的类
它创建时依赖于外部类对象
// 创建外部类对象
Outer o1 = new Outer();
// 创建内部类对象
Inner i1 = o1.new Inner();
// 一步到位
Inner i2 = new Outer().new Inner();
*当外部类与内部类有重名属性时,优先访问内部类
// 打印外部属性 // 内部类属性与外部类属性名相同,必须Outer.this.
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
// 打印内部类属性
System.out.println(this.name);
System.out.println(this.address);
System.out.println(this.phone);
成员内部类不能定义静态成员,但可以定义静态常量
②静态内部类static;
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
只有内部类才可以用static修饰
package com.common.member;
public class Outer {
private String name = "chenhao";
private int age = 8;
// 静态内部类 它的级别与外部类相同
static class Inner{
private String address = "shanghai";
private String phone = "111";
// 静态成员
private static int count = 1000;
public void show(){
// 调用外部类的属性
System.out.println(new Outer().name);
System.out.println(new Outer().age);
// 调用静态内部类的属性和方法
System.out.println(address);
System.out.println(phone);
// 调用静态内部类的静态属性
System.out.println(Inner.count);
}
}
}
// 如何去调用呢
package com.common.member;
public class TestOuter {
public static void main(String[] args) {
// 直接创建静态类对象
Outer.Inner I1 = new Outer.Inner();
// 调用方法
I1.show();
}
}
③局部内部类;
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法内(所以实例化时必须在方法内执行)
方法中若有局部变量,为了适应内部类,必然会有一个隐藏的final(jdk1.8以上),避免方法执行完,变量消失,导致局部内部类无法访问该变量。
package com.common.local;
public class Outer {
private String name = "chenhao";
private int age = 35;
public void show(){
// 定义局部变量 注意不能加任何访问修饰符
// 实际上这里是有一个隐藏的final 避免方法执行完,变量消失,导致局部内部类无法访问该变量
String address = "shenzhen";
// 局部内部类 注意不能加任何访问修饰符
class Inner{
// 属性
private String phone = "114514";
private String email = "244@163.com";
public void show2(){
// 访问外部类属性
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
// 访问内部类属性
System.out.println(phone);
System.out.println(email);
// 访问局部变量 jdk1.7 要加final jdk1.8 默认隐藏final;
// 所以不能修改这个变量
System.out.println(address);
}
}
// 创建局部内部类对象
Inner i1 = new Inner();
i1.show2();
}
}
// 如何调用
package com.common.local;
public class TestOuter {
public static void main(String[] args) {
Outer o1 = new Outer();
o1.show();
}
}
限制了类的使用范围
④匿名内部类
没有类名的局部内部类(特征一切与局部内部类相同)
必须继承一个父类或者实现一个接口
package com.common.anonymous;
// 接口
public interface Usb {
// 服务
void service();
}
// 实现
public class Mouse implements Usb {
@Override
public void service() {
System.out.println("连接电脑成功, 鼠标开始工作");
}
}
// 匿名实现
public class TestUsb {
public static void main(String[] args) {
Usb usb = new Usb(){
@Override
public void service() {
System.out.println("连接电脑成功, 风扇开始工作...");
}};
usb.service();
};
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
优点:减少代码量 缺点:可读性较差
匿名内部类出现后,字节码文件目录会出现一个自动命名的文件
2.Object类
java继承树的顶端-object
它是所有人的父类,或者间接的父类
所属方法
1getClass(){} 返回引用中存储的实际对象类型 用法:通常用于判断两个类是否一致
2hashCode(){} 返回该对象的hash值 int类型 用法:一般情况,相同对象返回相同的hash值
3toString(){} 返回该对象的字符串形式 用法:展示对象的各个属性值
我们一般都重写,符合我们的想法
4equals(Object obj){} 返回一个布尔值 用法:比较两个对象的地址是否相同
可以进行重写,改写比较规则
5finalize() 自动方法 被判定为垃圾对象时,JVM会自动调用,标记垃圾对象
垃圾对象:没有有效引用指向这个对象
垃圾回收:。。。
自动回收:JVM内存耗尽,一次性回收所有垃圾对象
手动回收:使用System.gc();通知JVM执行垃圾回收
3.包装类
a.基本数据类型对应的引用数据类型,
被包装后就可以使用方法了
基本数据类型存在栈里
而被引用的数据类型存在堆里
基本数据类型 | 包装类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
b.类型转换 拆箱和装箱
装箱:把基本类型转成引用类型,其实就是实例化一个对象
拆箱:把引用类型转成基本类型,将对象里的属性值拿出来
c.基本类型和字符串的转换
toString() 与 parseXXX()
特别注意:boolean中 “true” --> true 非"true"–>false
d.整数缓冲区–堆
java 内置了一个从(-128~127)的整数缓冲区
在自动装箱和拆箱时,都会去调这个整数缓冲区
为什么这么做?
因为这些值经常被使用,所以可以节省内存消耗
4.String
字符串是常量,创建后不可改变
字面值是存在字符串池中的,可以共享(栈,堆,方法区)
jdk1.7前,是在方法区里,1.7后改到堆里了
String name = "hello"; // 存储在字符串池里
name = "chenhao"; // 赋了新的值,没有修改数据,而是开辟了新的空间,原来的就成为垃圾
String name2 = "chenhao"; // 若发现池子里有这个内容,那么就会将栈的变量指向它。
// 所以 变量 name和name2里存的地址是一样的。
System.out.println("-----------------------------------------");
// 另一种创建字符串的方式
String str1 = new String("java"); // 堆里和方法区里都有内容。先指向堆,堆再指向池。实际内存里只会有一个,在池里。
String str2 = new String("java");
System.out.println(str1.equals(str2));
常用方法:
package com.common.string0;
import java.util.Arrays;
public class str0 {
public static void main(String[] args) {
String name = "hello"; // 存储在字符串池里
name = "chenhao"; // 赋了新的值,没有修改数据,而是开辟了新的空间,原来的就成为垃圾
String name2 = "chenhao"; // 若发现池子里有这个内容,那么就会将栈的变量指向它。
// 所以 变量 name和name2里存的地址是一样的。
System.out.println("--------------------字符串存储---------------------");
// 另一种创建字符串的方式
String str1 = new String("java"); // 堆里和方法区里都有内容。先指向堆,堆再指向池。实际内存里只会有一个,在池里。
String str2 = new String("java");
System.out.println(str1.equals(str2));
System.out.println("---------------------1字符串方法使用--------------------");
//1、length() 返回字符串长度
//2、charAt(int index) 返回某个位置的字符
//3、contains(String str) 判断是否包含某个字符串
String content = "chenyanbin";
System.out.println(content.length());
System.out.println(content.charAt(content.length()-1));
System.out.println(content.contains("chen"));
System.out.println(content.contains("yan"));
System.out.println("---------------------2字符串方法使用--------------------");
//4、toCharArray() 字符串转为数组
//5、indexOf(String str) 查找str首次出现下标索引, 若存在返回, 不存在返回-1
//6、lastIndexOf(String str) 查找str最后一次出现的下标索引
String content2 = "wuzhicheng wuzhicheng wuzhicheng";
System.out.println(Arrays.toString(content.toCharArray()));
System.out.println(content2.indexOf("wu"));
System.out.println(content2.indexOf("wu",2));
System.out.println(content2.lastIndexOf("wu"));
System.out.println("---------------------3字符串方法使用--------------------");
//7、trim() 去掉字符串前后的空格
//8、toUpperCase() 小写转大写 toLowerCase() 大写转小写
//9、endWith(String str) 判断字符串是否以str为结尾 返回boolean值 同理也有startWith(String str)
String content3 = " Dong JinWei ";
System.out.println(content3.trim());
System.out.println(content3.toUpperCase());
System.out.println(content3.toLowerCase());
System.out.println(content3.trim().endsWith("ei"));
System.out.println(content3.trim().startsWith("Do"));
System.out.println("---------------------4字符串方法使用--------------------");
//10、replace(char oldchar, char newchar) // 旧字符串转成新字符串
//11、split(String str) 对str做一个拆分
String content4 = "java is best programming language of the world. I love java";
System.out.println(content4.replace("java", "php"));
//String[] arr = content4.split(" "); //
//String[] arr = content4.split("[ ,]"); //用[] 表示里面的每个字符都会被用来分隔
String[] arr = content4.split("[ ,]+"); //用[]+ 表示里面的每个字符的连续多个都被视作一个 例如,,,
System.out.println(arr.length);
for(String stri : arr){
System.out.println(stri);
}
System.out.println("---------------------4.5字符串方法使用--------------------");
//12、equals(String str) 是否相等
//13、compareTo(String str) 比较对应下标字符串在 字典表里的位置 谁大谁小 并返回差值
//(只比较第1个,第1个相等则往后比较)(中文也可以)
String n1 = "hello";
String n2 = "HELLO";
System.out.println(n1.equals(n2));
System.out.println(n1.equalsIgnoreCase(n2)); // 忽略大小写比较
String n3 = "abc"; // a为97
String n4 = "xyz"; // x为120
System.out.println(n3.compareTo(n4));
String n5 = "abc"; //
String n6 = "abcxyz"; // 这种情况下, 完全相同的部分比完了, 那么比较字符串长度
System.out.println(n5.compareTo(n6));
}
}
String案例演示
package com.common.string0;
public class TestStrRepair {
public static void main(String[] args) {
StrRepair strRepair = new StrRepair("this is a text");
System.out.println(strRepair.getContent()); // 输出内容
// 1.单独获取str里的内容
String[] arr_str = strRepair.getStrAlone();
for (String s : arr_str) {
System.out.println(s);
}
// 2.将text替换为pratice
System.out.println(strRepair.replaceStr("text", "practice"));
// 3.在text前插入一个easy
System.out.println(strRepair.replaceStr("text", "easy text"));
// 4.将每个单词首字母改为大写
System.out.println(strRepair.getUpperCaseOfFirst(arr_str));
}
}
package com.common.string0;
public class StrRepair {
private String str0 = "";
public StrRepair(String str){
this.str0 = str; // 构造函数
}
public String[] getStrAlone(){
// 将str中的单词单独获取出来, 可根据下标访问
String[] arr = this.str0.split("[ ]+");
return arr;
}
public String replaceStr(String old_str, String new_str){
// 替换旧的字符串为新的
return this.str0.replace(old_str, new_str);
}
// public String insertStr(String ins_str, String ins_index){
// // 插入字符串到指定位置
// return this.str0.replace()
// }
public String getUpperCaseOfFirst(String[] arr_str){
// arr_str 中的每个单词首字母改为大写
String te_str = "";
for(String stri : arr_str){
Character temp_str = stri.charAt(0); // 提取首字母
stri.replace(temp_str.toString(), temp_str.toString().toUpperCase()); // 替换成大写形式
te_str += stri+" ";
}
te_str = te_str.trim();
return te_str;
}
public String getContent(){
// 返回值
return this.str0;
}
public int getLength(){
return this.str0.length();
}
}
可变字符串:
package com.common.string0;
public class VariableStr {
// 可变字符串
// JDK1.0 StringBuffer 缓冲区内操作 运行效率相对Builder慢, 比string快 线程安全
// JDK5.0 StringBuilder 运行效率快, 线程不安全
// 两者方法一致 尽量用StringBuilder
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
//1.append 追加
System.out.println("----------------append 追加----------------");
sb.append("java 1st");
System.out.println(sb.toString());
sb.append(", java nice");
System.out.println(sb.toString());
sb.append(", java good");
System.out.println(sb.toString());
//2.insert 插入添加
System.out.println("----------------insert 插入添加----------------");
sb.insert(0, "I am front, ");
System.out.println(sb.toString());
//3.replace 替换 不同:可以替换指定位置
System.out.println("----------------replace 替换----------------");
sb.replace(0,4,"hello");
System.out.println(sb.toString());
//4.delete 删除 可以删除指定位置
System.out.println("----------------delete 删除----------------");
sb.delete(0, 6);
System.out.println(sb.toString());
// 清空
sb.delete(0, sb.length());
System.out.println(sb.length());
}
}
5.BigDecimal类
位于java.math包中
作用是精确计算浮点数
方法加减乘除
package com.common.bigdm;
import java.math.BigDecimal;
public class Demo0 {
public static void main(String[] args) {
// double 存的是近似值 会导致误差 但在精度较高的情况下不允许
double d1 = 1.0;
double d2 = 0.9;
System.out.println(d1-d2);
System.out.println("------------------BigDecimal类------------------");
// 所以需要 BigDecimal类 大浮点数精确计算
// 一定要用字符串
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("0.9");
// 减法
BigDecimal r1 = bd1.subtract(bd2);
System.out.println(r1);
// 加法
BigDecimal r2 = bd2.add(bd1);
System.out.println(r2);
// 乘法
BigDecimal r3 = bd2.multiply(bd1);
System.out.println(r3);
// 除法
BigDecimal r4 = new BigDecimal("1.4")
.subtract(new BigDecimal("0.5"))
.divide(new BigDecimal("0.9"));
System.out.println(r4);
// 无限小数
BigDecimal r5 = new BigDecimal("10")
.divide(new BigDecimal("3"),2,BigDecimal.ROUND_HALF_UP); // Round_Half_up四舍五入
System.out.println(r5);
}
}
6.时间类型
Date类
package com.common.timing;
import java.util.Date;
public class Date0 {
public static void main(String[] args) {
// 1 Date 对象
// 当前时间
Date date1 = new Date();
System.out.println(date1.toString());
System.out.println(date1.toLocaleString());
// 昨天时间
Date date2 = new Date(date1.getTime()-60*60*24*1000); //ms计时
System.out.println(date2.toLocaleString());
// 2 after before 判断日期是否在前或后
boolean b1 = date1.after(date2);
System.out.println(b1);
// 比较 compareTo(); 毫秒值相减, 有正负
int d = date1.compareTo(date2);
System.out.println(d);
// 判断是否相等 equals();
boolean e = date1.equals(date2);
System.out.println(e);
}
}
Calendar
package com.common.timing;
import java.util.Calendar;
public class Calendar0 {
public static void main(String[] args) {
// Calendar 是protected 提供了获取或设置各种日历字段的方法
// 1 创建一个对象
Calendar cal1 = Calendar.getInstance(); //
System.out.println(cal1.getTime().toLocaleString());
System.out.println(cal1.getTimeInMillis()); //获取从基准时间到现在的毫秒值
// 2 获取时间信息
// 获取各种时间信息
// 年
int year = cal1.get(Calendar.YEAR);
// 月
int month = cal1.get(Calendar.MONTH);
// 日
int day = cal1.get(Calendar.DAY_OF_MONTH);
// 小时
int hour = cal1.get(Calendar.HOUR_OF_DAY); // HOUR 12小时进制; HOUR_OF_DAY 24小时进制
// 分钟
int minute = cal1.get(Calendar.MINUTE);
// 秒
int second = cal1.get(Calendar.SECOND);
System.out.println(year+"年"+(month+1)+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒");
// 3 set方法修改时间
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.DAY_OF_MONTH, 5); // 修改日
System.out.println(cal2.getTime().toLocaleString());
// 4 add方法修改时间
cal2.add(Calendar.HOUR, 1);
System.out.println(cal2.getTime().toLocaleString());
// 5 补充方法
cal2.add(Calendar.MONTH,1);
int max = cal2.getActualMaximum(Calendar.DAY_OF_MONTH);
int min = cal2.getActualMinimum(Calendar.DAY_OF_MONTH);
System.out.println(max);
System.out.println(min);
}
}
SimpleDateFormat
可以根据语言环境来格式化和解析日期的具体类
即 进行格式化和解析 日期->文本;文本->日期
package com.common.timing;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormat0 {
public static void main(String[] args) throws ParseException {
// 1 创建SimpleDateFormat 对象
// y->year; M->month;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH-mm-ss");
// 2 创建Date
Date date = new Date();
// 格式化date 日期->文本
String str_time = sdf.format(date);
System.out.println(str_time);
// 解析 文本->日期
Date date2 = sdf.parse("1990/05/04");
System.out.println(date2);
}
}
System类
私有 不用创建对象 直接调用
package com.common.system0;
public class Demo0 {
public static void main(String[] args) {
// 1 arraycopy: 数组复制
// src: 源数组;
// srcPos: 从哪个位置开始复制;
// dest: 目标数组
// destPos: 复制到哪个位置;
// length: 复制的长度
int[] src_arr = {18,45,26,76,34,2,103};
int[] des_arr = new int[8];
System.arraycopy(src_arr, 0, des_arr, 0, src_arr.length);
for (int j : des_arr) {
System.out.println(j);
}
/* 对比python的for循环加强写法
for i in des_arr:
print(i)
*/
// 2 可用于时间计算
System.out.println(System.currentTimeMillis());
long start = System.currentTimeMillis();
for (int i = 0; i < 99999999; i++) {
for (int j = 0; j < 99999999; j++) {
int result = i+j;
}
}
long end = System.currentTimeMillis();
System.out.println("用时"+(end-start)+"s");
// 3 System.gc(); 通知垃圾回收器 准备回收
new Student("aaa",10);
new Student("bbb",11);
new Student("ccc",12);
new Student("ddd",13);
System.gc();
// 4 退出JVM 可提前
System.exit(0);
System.out.println("程序已经结束了");
}
}