零散知识点
- 所有java程序由
public static void main(String[] args) { }
开始执行 - 一个源文件中只能有一个public类,可以有多个非public类。源文件的名称应该和public类的名称保持一致
- 如果一个类定义在某个包中,那么package语句应该在源文件的首行。同一个包中的类可以相互引用。如下所示:
package com.example.lib;
Snip20180709_3.png
如果源文件中还包含import语句,那么应该放在package语句和类定义之间,如果没有package语句,那么import语句应该在源文件最前面。
import语句和package语句对源文件中定义的所有类都有效。 - Java包,包主要用来对类和接口进行分类。当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
- Import语句。在Java中,如果给出一个完整的限定名,包括包名、类名,那么Java编译器就可以很容易地定位到源代码或者类。Import语句就是用来提供一个合理的路径,使得编译器可以找到某个类。
import java.lang.System;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
这几行说明了这四个姓名的类别,在程式中只用他的名字来称呼,所以当程式
中提到 System 就是指 java.lang.System,而 InputStream 就是指java.io.InputStream,依此类推。
- instalceOf 该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。其使用格式如下:
(Object reference variable) instanceOf (class / interface type)
//Demo
String name = 'James';
boolean result = name instanceOf String;
- Java增强for循环
for(声明语句 :表达式) {
//代码句子
}
//Demo
int [] numbers = {10,20,30};
for (int x : numbers) {
}
数据类型
内置数据类型
- byte 8位带符号整数
- short 16位带符号整数
- int 32位带符号整数
- long 64位带符号整数
- float 32位浮点数
- double 64位浮点数
- boolean 只有两个值true/false
- char 一个单一的16位Unicode字符
引用类型
引用类型变量由类的构造函数创建,可以使用它们访问所引用的对象。
常量
常量指不能改变的值,在Java中用final标志,声明方式和变量类似:
final double PI = 3.1415927;
Java Number类
在开发过程中,经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java语言为每一个内置数据类型提供了对应的包装类。所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类Number的子类。
public class Test{
public static void main(String args[]){
Integer x = 5; // boxes int to an Integer object
x = x + 10; // unboxes the Integer to a int
System.out.println(x);
}
}
当x被赋值为整型的时候,由于x是一个对象,所以编译器要对x进行装箱,然后,为了使x能进行加运算,所以要对x进行拆箱。
变量类型
声明变量的基本格式如下:
type identifier [ = value][, identifier [= value] ...] ;
- 局部变量,声明在方法、构造方法或者语句块中;访问修饰符不能用于局部变量;
- 实例变量(或者称为成员变量),声明在类中,但在方法、构造方法和语句块之外;访问修饰符可以修饰实例变量;
- 类变量,也称为静态变量,在类中以static关键字声明,但必须在方法、构造方法和语句块之外;静态变量可以通过:ClassName.VariableName的方式访问。
public class Dog {
//类变量
private static double salary;
//成员变量
//这个成员变量对子类可见
public String bread;
//私有变量,仅在该类中可见
private int age;
String color;
void barking() {
//局部变量
int age = 7;
System.out.println("Dog age is :" + age);
System.out.println("barking");
}
}
Java修饰符
访问修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限:
- 默认,在同一包内可见,不使用任何修饰符
- 私有的 private ,在同一类内可见。类和接口不能声明位private
- 共有的 public ,对所有类可见
- 受保护的 protected ,对同一包内的类和所有子类可见。
访问控制和继承
- 父类中声明为public的方法在子类中也必须为public
- 父类中声明为protected的方法在子类中要么声明为protected,要么声明为public,不能声明为private
- 父类中默认修饰符声明的方法,能够在子类中声明为private
- 父类中声明为private的方法,不能被继承
非访问修饰符
- static ,用来创建类方法和类变量。Static关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。
- final,用来修饰类、方法和变量,final修饰的类不能被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
- Abstract ,用来创建抽象类和抽象方法。
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被abstract和final修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。抽象类可以包含抽象方法和非抽象方法
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。 - Synchronized和volatile 主要用于线程的编程。
Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。一个volatile对象引用可能是null。
Java Math类
Math包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方和三角函数。
Math的方法都被定义为static形式,通过Math类可以在主函数中直接调用。
public class Test {
public static void main (String []args)
{
System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2));
System.out.println("0度的余弦值:" + Math.cos(0));
System.out.println("60度的正切值:" + Math.tan(Math.PI/3));
System.out.println("1的反正切值: " + Math.atan(1));
System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2));
System.out.println(Math.PI);
}
}
Character类
Character类是Java语言为内置数据类型char提供的包装类。
Character ch = new Character('a');
Character ch1 = 'a'; //自动创建Character对象
Character部分方法
方法 | 描述 |
---|---|
isLetter() | 是否是一个字母 |
isDigit() | 是否是一个数字字符 |
isWhitespace() | 是否是空格 |
isUpperCase() | 是否是大写字母 |
isLowerCase() | 是否是小写字母 |
toUpperCase() | 指定字母的大写形式 |
toLowerCase() | 指定字母的小写形式 |
toString() | 返回字符的字符串形式,字符串长度仅为1 |
String类
连接字符串
String str1 = "aaa";
String str2 = "bbb";
String concatStr1 = str1.concat(str2);
String concatStr2 = str1 + str2;
System.out.println(concatStr1);
System.out.println(concatStr2);
创建格式化字符串
String str1 = "aaa";
String str2 = "bbb";
System.out.printf("str1 is : %s" + "str2 is : %s\n",str1,str2);
String fs = String.format("str1 is : %s" + "str2 is : %s",str1,str2);
System.out.println(fs);
String部分方法
方法 | 描述 |
---|---|
char charAt(int index) | 返回指定索引处的 char 值。 |
int compareTo(Object o) | 把这个字符串和另一个对象比较。 |
int compareTo(String anotherString) | 按字典顺序比较两个字符串。 |
int compareToIngoreCase(String str) | 按字典顺序比较两个字符串,不考虑大小写。 |
boolean contentEquals(StringBuffer sb) | 将指定字符串连接到此字符串的结尾。 |
StringBuffer和StringBuilder类
和String类不同,StringBuffer和StringBuilder类的对象能够被多次修改,并且不产生新的未使用对象。
StringBuffer和StringBuilder之间最大的不同在于StringBuilder的方法不是线程安全的。
StringBuffer sBuffer = new StringBuffer(" test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);
StringBuffer类支持的主要方法:
方法 | 描述 |
---|---|
public StringBuffer append(String s) | 将指定的字符串追加到此字符序列。 |
public StringBuffer reverse() | 将此字符序列用其反转形式取代。 |
public delete(int start, int end) | 移除此序列的子字符串中的字符。 |
public insert(int offset, int i) | 将 int 参数的字符串表示形式插入此序列中。 |
replace(int start, int end, String str) | 使用给定 String 中的字符替换此序列的子字符串中的字符。 |
数组
声明数组变量的语法:
dataType[] arrayRefVar; // 首选的方法
或
dataType arrayRefVar[]; // 效果相同,但不是首选方法
创建数据的语法:
dataType[] arrayRefVar = new dataType[arraySize];
日期时间
java.util包提供了Date类来封装当前的日期和时间,Date类提供两个构造函数来实例化Date对象:
Date() //使用当前时间和日期来初始化对象
或
Date(long milliseconds) //接收一个参数,该参数是自1970年1月1日起的微秒数
Date对象方法:
方法 | 描述 |
---|---|
boolean after(Date date) | 若当调用此方法的Date对象在指定日期之后返回true,否则返回false。 |
boolean before(Date date) | 若当调用此方法的Date对象在指定日期之前返回true,否则返回false。 |
Object clone( ) | 返回此对象的副本。 |
int compareTo(Date date) | 比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。 |
int compareTo(Object obj) | 若obj是Date类型则操作等同于compareTo(Date) 。否则它抛出ClassCastException。 |
long getTime( ) | 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。 |
int hashCode( ) | 返回此对象的哈希码值。 |
void setTime(long time) | 用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。 |
String toString( ) | 转换Date对象为String表示形式,并返回该字符串。 |
使用SimpleDateFormat格式化日期
Date dNow = new Date( );
SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
System.out.println("Current Date: " + ft.format(dNow));
//输出结果为:Current Date: 星期二 2018.07.10 at 02:29:17 下午 CST
解析字符串为时间
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd");
String input = "1818-11-11";
System.out.print(input + " Parses as ");
Date t;
//必须异常捕获
try {
t = ft.parse(input);
System.out.println(t);
} catch (ParseException e) {
System.out.println("Unparseable using " + ft);
}
休眠
//必须异常捕获
try {
Thread.sleep(5*60*10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Calendar类
通过使用Calendar类,可以获取日期数据的特点部分,比如小时、日或者分钟。Calendar类是一个抽象类,在实际使用时实现特点的子类对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
Calendar c = Calendar.getInstance();//默认是当前日期
//创建一个代表2009年6月12日的Calendar对象
Calendar c1 = Calendar.getInstance();
c1.set(2009, 6 - 1, 12);
Calendar类对象字段类型
常量 | 描述 |
---|---|
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份 |
Calendar.DATE | 日期 |
Calendar.DAY_OF_MONTH | 日期,和上面的字段意义完全相同 |
Calendar.HOUR | 12小时制的小时 |
Calendar.HOUR_OF_DAY | 24小时制的小时 |
Calendar.MINUTE | 分钟 |
Calendar.SECOND | 秒 |
Calendar.DAY_OF_WEEK | 星期几 |
Calendar对象信息的设置
Calendar c1 = Calendar.getInstance();
//设置年份
c1.set(c1.YEAR,2008);
// 获得年份
int year = c1.get(Calendar.YEAR);
System.out.println(year); //2008
//年份加10
c1.add(Calendar.YEAR, 10);
year = c1.get(Calendar.YEAR);
System.out.println(year); //2018
GregorianCalendar类
Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。提供了世界上大多数国家/地区使用的标准日历系统。
String months[] = {
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"};
int year;
// 初始化 Gregorian 日历
// 使用当前时间和日期
// 默认为本地时间和时区
GregorianCalendar gcalendar = new GregorianCalendar();
// 显示当前时间和日期的信息
System.out.print("Date: ");
System.out.print(months[gcalendar.get(Calendar.MONTH)]);
System.out.print(" " + gcalendar.get(Calendar.DATE) + " ");
System.out.println(year = gcalendar.get(Calendar.YEAR));
System.out.print("Time: ");
System.out.print(gcalendar.get(Calendar.HOUR) + ":");
System.out.print(gcalendar.get(Calendar.MINUTE) + ":");
System.out.println(gcalendar.get(Calendar.SECOND));
// 测试当前年份是否为闰年
if(gcalendar.isLeapYear(year)) {
System.out.println("当前年份是闰年");
}
else {
System.out.println("当前年份不是闰年");
}
Java 正则表达式
正则表达式可以用来搜索、编辑或处理文本。
java.util.regex包主要包括以下三类:
- Pattern类
pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其公共静态编译方法,它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数。 - Matcher类:
Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象。 - PatternSyntaxException:
PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
方法
可变参数
JDK1.5开始,Java支持传递同类型的可变参数给一个方法。其声明如下:
typeName... parameterName
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通参数必须在它之前声明。
public static void main(String args[]) {
// 调用可变参数的方法
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3});
}
public static void printMax( double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for (int i = 1; i < numbers.length; i++) if (numbers[i] > result)
result = numbers[i];
System.out.println("The max value is " + result);
}
finalizer()方法
finalizer()方法在对象被垃圾收集器析构(回收)之前调用,它用来清除回收对象。
public class MyClass {
public static void main(String[] args) {
Cake c1 = new Cake(1);
Cake c2 = new Cake(2);
Cake c3 = new Cake(3);
c2 = c3 = null;
System.gc(); //调用Java垃圾收集器
}
}
class Cake extends Object {
private int id;
public Cake(int id) {
this.id = id;
System.out.println("Cake Object " + id + "is created");
}
protected void finalize() throws java.lang.Throwable {
super.finalize();
System.out.println("Cake Object " + id + "is disposed");
}
}
//打印结果为:
Cake Object 1is created
Cake Object 2is created
Cake Object 3is created
Cake Object 3is disposed
Cake Object 2is disposed
文件操作
读取文件内容
String encoding = "UTF-8";
File file = new File("/Users/liboxiang/Desktop/test.java");
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
try {
FileInputStream in = new FileInputStream(file);
in.read(filecontent);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
String contentStr = new String(filecontent, encoding);
//输出文件内容
System.out.println(contentStr);
} catch (UnsupportedEncodingException e) {
System.err.println("The OS does not support " + encoding);
e.printStackTrace();
}
写文件操作
String encoding = "UTF-8";
File file = new File("/Users/liboxiang/Desktop/test.java");
try {
FileOutputStream fop = new FileOutputStream(file);
try {
OutputStreamWriter writer = new OutputStreamWriter(fop,encoding);
try {
writer.append("萝卜心");
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
fop.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
创建目录
File类中有两个方法可以用来创建文件夹:
- mkdir()方法创建一个文件夹,成功则返回true,失败则返回false。失败表明File对象指定的路径已经存在,或者由于整个路径还不存在,该文件夹不能被创建。
- mkdirs()方法创建一个文件夹和它的所有父文件夹。
String dirname = "/tmp/user/java/bin";
File d = new File(dirname);
// 现在创建目录
d.mkdirs();
读取目录
一个目录其实就是一个File对象,它包含其他文件和文件夹。
如果创建一个File对象并且它是一个目录,那么调用isDirectory()方法会返回true。
可以通过调用该对象的list()方法来提取它包含的文件和文件夹的列表。
String dirname = "/Users/liboxiang/Desktop";
File f1 = new File(dirname);
if (f1.isDirectory()) {
String [] s = f1.list();
for (int i = 0; i < s.length; i++) {
System.out.println(s[i] + "\n");
}
}
继承
继承中最常使用的两个关键字是extends和implements。这两个关键字的使用决定了一个对象和另一个对象是否是IS-A(通过instanceof操作符判断)关系。
所有的Java的类均是有java.lang.Object类继承而来的,所以Object是所有类的祖先类,而除类Object外,所有类必须有一个父亲。
// A.java
public class A {
private int i;
protected int j;
public void func() {
}
}
// B.java,继承于A
public class B extends A {
}
implements一般是实现接口。extends 是继承类。 接口一般是只有方法声明没有定义的。implements实现父类,子类不可以覆盖父类的方法或者变量。即使子类定义与父类相同的变量或者函数,也会被父类取代掉。
public interface people(){
public say();
}
public class chinese implements people{
public say(){
System.out.println("你好!");
}
}
抽象类
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类除了不能实例化对象之外,类的其他功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
抽象类不能实例化对象,所以抽象类必须被继承才能使用。
在Java语言中用abstract class来定义抽象类:
abstract class Employee {
public void mailCheck()
{
System.out.println("Mailing a check to ");
}
}
class Salary extends Employee {
public void mailCheck()
{
System.out.println("Within mailCheck of Salary class ");
}
}
public class MyClass {
public static void main(String[] args) {
Salary s = new Salary();
Employee e = new Salary();
s.mailCheck();
e.mailCheck();
}
}
抽象方法
如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
Abstract关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
声明抽象方法会造成以下两个结果:
- 如果一个类包含抽象方法,那么该类必须是抽象类。
- 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
public abstract double computePay();
接口
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键子。接口中的方法都是公有的。
interface Animal {
public void eat();
public void travel();
}
接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
接口的继承
一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
接口的多重继承
在Java中,类的多重继承是不合法,但接口允许多重继承。
public interface Hockey extends Sports, Event
网友评论