内部类
- 概念:在一个类的内部再定义一个完整的类,当外部类与内部类的属性重名时,优先访问内部类属性
- 分类:成员内部类、静态内部类、局部内部类、匿名内部类
成员内部类
- 内部类在编译之后也会产生独立的字节码文件
- 成员内部类在类的内部定义,与外部类的变量和方法同级别的类
- 成员内部类可以直接拿到外部类的私有属性
- 如果存在同名属性,优先访问成员内部类的属性
- 成员内部类里不能定义静态成员变量,但是可以定义静态常量(final),这个静态常量在不实例化外部类的情况下可以调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class Outer{ private int id = 10; private String name = "张三";
public void out(){ System.out.println("这是外部方法"); }
public class Inner { static final String XXX = "这是一个静态常量"; private String name = "李四"; public void in(){ System.out.println("这是内部方法"); System.out.println(name); System.out.println(this.name); System.out.println(Outer.this.name); }
public void getID(){ System.out.println(id); } } }
|
实例化成员内部类
1 2 3 4 5 6 7 8 9 10 11
| public class Test { public static void main(String[] args) { String xxx = Outer.Inner.XXX; System.out.println(xxx);
Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.getID(); } }
|
静态内部类
- 静态内部类不依赖外部类对象,可直接创建或通过类名访问,可以定义静态成员变量
- 非静态内部类需要在外部类存在一个实例时才可以调用,静态内部类可以直接调用,因为没有一个外部类的实例,所以在静态内部类里面不可以直接访问外部类的属性和方法,若想访问,需要创建外部类的对象来调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Outer{
private String name = "xxx"; private int age = 20;
static class Inner{ private String address = "上海"; private String phone = "111"; private static int count = 1000;
public void show(){ Outer outer = new Outer();
System.out.println(outer.name); System.out.println(outer.age);
System.out.println(address); System.out.println(phone);
System.out.println(Inner.count); } } }
|
局部内部类
- 局部内部类就是定义在外部类的方法里面的类,作用范围和创建对象范围仅限于当前方法,不能添加任何修饰符
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同(局部变量在方法执行之后消失,而内部类不会消失),变量必须修饰为final常量,这是JDK1.7的规定,JDK1.8以后,这个final会自动添加,不用我们考虑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Outer{ private String str1 = "外部类变量"; public void method(){ class Inner{ private String str = "局部变量";
public void in(){ System.out.println(str1);
System.out.println(str); } }
Inner inner = new Inner(); inner.in(); }
public static void main(String[] args) { new Outer().method(); } }
|
匿名内部类
- 匿名内部类也就是没有名字的局部内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写,但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口
- 匿名类就是在实例化类的重写方法,不使用引用保存实例
1 2 3 4 5
| public class Test { public static void main(String[] args) { new Outer().method(); } }
|
在接口上使用匿名内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| interface Person { public void eat(); } public class Demo { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } }
|
最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口
1 2 3 4 5 6 7 8 9 10 11 12
| public class Demo { public static void main(String[] args) { Thread t = new Thread() { public void run() { for (int i = 1; i <= 5; i++) { System.out.print(i + " "); } } }; t.start(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Demo { public static void main(String[] args) { Runnable r = new Runnable() { public void run() { for (int i = 1; i <= 5; i++) { System.out.print(i + " "); } } }; Thread t = new Thread(r); t.start(); } }
|
Object
Object类是所有类的超类,所有类默认继承Object类
getClass()
返回引用中存储的实际对象类型
1 2
| Student stu = new Student(); Class class = stu.getClass();
|
hashCode()
返回对象哈希值,是一个整数,表示在哈希表中的位置
哈希值:根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值,一般情况下,相同对象返回相同哈希码
1 2
| Student stu = new Student(); int hash = stu.hashCode();
|
toString()
返回该对象的字符串表示,因为默认打印的是类的内存地址,所以通常我们都会重写这个方法,达到输出字符串的目的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Student { private String name; private int age;
public Student(String name, int age){ this.name = name; this.age = age }
public String toString() { return "name:" + name + "age:" + age; } }
Student stu = new Student("张三",20); String stuInfo = stu.toString();
|
equals()
比较两个对象地址是否相同,这个方法在String中被重写了,重写后的方法先对比引用地址,如不相同则对比字面值
1 2 3
| Student stu1 = new Student(); Student stu2 = new Student(); boolean result = stu1.equals(stu2);
|
finalize()
垃圾回收方法,由JVM自动调用此方法
- 垃圾对象:没有有效引用指向此对象
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
- 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
- 手动回收机制:使用System.gc();通知JVM执行垃圾回收
String
创建字符串的两种方式及区别
1 2 3 4 5
| String str1 = "你好";
String str2 = new String("Hello World");
|
length()
返回字符串长度
1 2
| String str = "Hello World"; int leng = str.length();
|
charAt(int index)
返回某个位置的字符
1 2
| String str = "Hello World"; char c = str.charAt(0);
|
contains(String str)
判断是否包含某个子字符串,返回布尔值
1 2
| String str = "Hello World"; boolean result = str.contains("Hello");
|
toCharArray()
将字符串转换为字符数组返回
1 2
| String str = "Hello World"; char[] strs = str.toCharArray();
|
indexOf(String str)
查找str首次出现的下标,返回,如果不存在,返回-1
1 2 3 4
| String str = "Hello World"; int index = str.indexOf("Hello");
int index = str.indexOf("Hello",4);
|
lastIndexOf(String str)
查找字符串在当前字符串中最后一次出现的下标,返回,如果不存在,返回-1;
1 2
| String str = "Java Hello Java CC Java"; int index = str.lastIndexOf("Java");
|
trim()
去掉字符串前后空格
1 2
| String str = " Hello World "; String str2 = str.trim();
|
toUpperCase()
将小写转成大写
toLowerCase()
将大写转换成小写
1 2 3
| String str = "Hello World"; String str2 = str.toUpperCase(); String str3 = str.toLowerCase();
|
endsWith(String str)
判断字符串是否以str结尾
startsWith(String str)
判断字符串是否以str开头
1 2 3
| String str = "Hello World"; boolean r1 = str.startsWith("Hello"); boolean r2 = str.endsWith("World");
|
replace(char oldChar,char newChar)
将旧字符串替换成新字符串
1 2
| String str = "Hello World"; String str2 = str.replace("World","Java");
|
split(String str)
根据str对字符串进行拆分,返回一个字符串数组
1 2 3 4 5
| String str = "Hello World Java PHP C,Python|C++";
String[] strs = str.split(" ")
String[] strs = str.split("[ ,|]")
|
可变字符串
StringBuffer : 可变长字符串,运行效率慢、线程安全
StringBuilder : 可变长字符串、运行快、线程不安全
StringBuffer和StringBuilder的效率都高于String,都比String节省内存
StringBuffer和StringBuilder的用法是一样的,StringBuilder的效率高于StringBuffer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| StringBuilder sb = new StringBuilder();
sb.append("Hello World");
sb.insert(0,"Hello World");
sb.replace(6,11,"Java");
sb.delete(6,sb.length());
sb.toString();
|
BigDecimal
- float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,然而,它们没有提供完全精确的结果。但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| BigDecimal bd1 = new BigDecimal("1.0"); BigDecimal bd2 = new BigDecimal("0.9");
BigDecimal result1 = bd1.add(bd2);
BigDecimal result2 = bd1.subtract(bd2);
BigDecimal result3 = bd1.multiply(bd2);
BigDecimal result4 = bd1.divide(bd2);
BigDecimal result5 = bd1.divide(bd2).setScale(2, RoundingMode.HALF_UP)
|
Date
- Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public static void main(String[] args) { Date date1 = new Date(); System.out.println(date1.toString()); System.out.println(date1.toLocaleString());
Date date2 = new Date(date1.getTime() - (60*60*24*1000)); System.out.println(date2.toLocaleString());
boolean b1 = date1.after(date2); System.out.println(b1); boolean b2 = date1.before(date2); System.out.println(b2);
int d = date1.compareTo(date1); System.out.println(d);
boolean b3 = date1.equals(date2); System.out.println(b3); }
|
Calendar
- Calendar提供了获取或设置各种日历字段的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); System.out.println(calendar.getTime().toLocaleString()); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); Calendar calendar2 = Calendar.getInstance(); calendar2.set(Calendar.DAY_OF_MONTH, x); calendar2.add(Calendar.HOUR, x); int max = calendar2.getActualMaximum(Calendar.DAY_OF_MONTH); int min = calendar2.getActualMinimum(Calendar.DAY_OF_MONTH); }
|
- SimpleDateFormat是一个以与语言环境有关的方式来格式化和解析日期的具体类
1 2 3 4 5 6 7 8 9 10 11 12
| public static void main(String[] args) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH-mm-ss"); Date date = new Date(); String str = sdf.format(date); System.out.println(str); Date date2 = sdf.parse("1948/03/12"); System.out.println(date2); }
|
System
- 主要用于获取系统的属性数据和其他操作,构造方法私有化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static void main(String[] args) { int[] arr = {20, 18, 39, 3}; int[] dest = new int [4]; System.arraycopy(arr, 0, dest, 0, 4); for (int i : dest) { System.out.println(i); }
System.currentTimeMillis();
}
|