- Java源程序文件的后缀是.java,Java字节码文件的后缀名称是.classJava语言的三个分支是:JAVA SE、ME、EEJava程序实现可移值性,依靠的是JVMjavac hello.java ; java hello
- 新建系统变量 JAVA_HOME ,安装路径新建系统变量 PATH,%JAVA_HOME%bin;%JAVA_HOME%jrebin;或者是直接%JAVA_HOME%bin;新建系统变量CLASSPATH,.;%JAVA_HOME%libdt.jar;%JAVA_HOME%libtools.jar;
enum 关键字来定义,各个常量使用逗号
enum Color
{
RED, GREEN, BLUE;
}
public class Test {
public static void main(String[] args) {
Color c1 = Color.RED;
System.out.println(c1);
}
}
枚举类也可以声明在内部类中
public class Test
{
enum Color
{
RED, GREEN, BLUE;
}
// 执行输出结果
public static void main(String[] args)
{
Color c1 = Color.RED;
System.out.println(c1);
}
}
迭代枚举元素
for (Color myVar : Color.values()) {
System.out.println(myVar);
}
在 switch 中使用枚举类
switch(myVar) {
case RED:
System.out.println("红色");
break;
case GREEN:
System.out.println("绿色");
break;
case BLUE:
System.out.println("蓝色");
break;
}
values(), ordinal() 和 valueOf() 方法
enum Color
{
RED, GREEN, BLUE;
}
public class Test {
public static void main(String[] args) {
Color[] arr = Color.values(); // 调用 values()
for (Color col : arr) { // 迭代枚举
System.out.println(col + " at index " + col.ordinal()); // 查看索引
}
// 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException
System.out.println(Color.valueOf("RED"));
// System.out.println(Color.valueOf("WHITE"));
}
}
枚举类成员
- 枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。
enum Color
{
RED, GREEN, BLUE;
// 构造函数
private Color(){
System.out.println("Constructor called for : " + this.toString());
}
public void colorInfo(){
System.out.println("Universal Color");
}
}
public class Test {
public static void main(String[] args) {
Color c1 = Color.RED;
System.out.println(c1);
c1.colorInfo();
}
}
String
equals和==
- ==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同==是指对内存地址进行比较 , equals()是对字符串的内容进行比较==指引用是否相同(对象), equals()指的是值是否相同"Hello".equals(a)
//多个字符串放在一起,分割,可以用静态join方法
String all = String.join("/","S","M","L");// S/M/L
String greeting = "Hello";
string s = greeting.substring(0,3);//Hel,截头不截尾
//调用s.charAt(n)返回位置n的代码单元
char first= greeting.charAt(0);//H
char last= greeting.charAt(4);//o
运算符
- 三元运算符 C=A>B ? 100 :200; 如果A>B的话,就将100赋给C,否则就将200赋给C;%(取余数)
通过Scanner类的 next()与nextLine()获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。next()不能得到带有空格的字符串。nextInt()、nextDouble()等等。
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
//创建一个扫描器对象,获取输入数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收: ");
// String str = scanner.next();
//判断用户有没有输入
if (scanner.hasNext()){
//使用next方式接收
String str = scanner.next();
System.out.println("输出的内容为"+str);
}
Scanner scanner2 = new Scanner(System.in);
System.out.println("使用nextLine方式接收: ");
if (scanner2.hasNextLine()){
//使用nextLine方式接收
String str = scanner2.nextLine();
System.out.println("输出的内容为"+str);
}
scanner.close();
}
}
for.each
for(初始化;布尔表达式;更新){
//int i=1;i<=100;i++(重复完内容后i才加1)
}
//增强for循环,数组集合类
//遍历数组的元素
int[] numbers = {10,20,30};
for(int x:numbers){
sout(x);
}
//break跳出循环
//continue跳出某次循环
方法
可变参数
//JDK1.5开始,Java支持传递同类型的可变参数给一个方法。其后面加...,一个方法只能有一个可变参数。必须放在参数的最后
public void test(int x,int... i){
}
-------------------------------------------
int randomNum = (int) (Math.ramdom( )*5)//获取一个0-4的随机数
Integer.parseInt("3");//将String转换成int
数组
定义数组
- java.lang.ArrayIndexOutOfBoundsException数组越界数组定义后大小不可改变数组对象本身是在堆中的定义数组必须是相同类型,不可混杂
//静态初始化:创建+赋值
int[] a = {1,2,3};
//动态初始化:包含默认值初始化
int[] b = new int [10];
b[0]= 1;
Arrays
import java.util.Arrays;
public class ArraysTest {
public static void main(String[] args) {
int[] a = new int[]{3,4,5,6};
int[] a2 = new int[]{3,4,5,6};
System.out.println(Arrays.equals(a,a2));//判断是否相等
int[] b = Arrays.copyOf(a, 6); //复制a,长度为6,多的补0
System.out.println(Arrays.toString(b));//打印数组b
Arrays.fill(b,2,4,1);//3~5(不包括),赋值为1
System.out.println(Arrays.toString(b));
Arrays.sort(b);//升序
System.out.println(Arrays.toString(b));
}
}
//true
//[3, 4, 5, 6, 0, 0]
//[3, 4, 1, 1, 0, 0]
//[0, 0, 1, 1, 3, 4]
//二维数组
int array[][] = new int[][]{{1,2},{2,3}};
int[][] array ={{1,2},{3,4},{5,6}};
int[] a={1,2,3,4};
System.out.println(array);//[[I@1540e19d
System.out.println(array[1][1]);//输出4
//打印数组元素Arrays.toString
System.out.println(Arrays.toString(a));//[1, 2, 3, 4]
System.out.println(Arrays.toString(array));//[[I@677327b6, [I@14ae5a5, [I@7f31245a]
ArrayList
//1.创建 ArrayListmyList = new ArrayList ();//新的ArrayList对象会创建在堆上 //2.加入元素 Egg a = new Egg(); myList.add(a);//此ArrayList会产生一个盒子来放Egg对象 //3.再加入元素 Egg b = new Egg(); myList.add(b); //4.查询大小 int theSize = myList.size();//2 //5.查询特定元素 boolean isIn = myList.contains(a);//myList带有a所引用的Egg对象,返回true //6.查询元素位置 int idx = myList.indexOf(b);//1 //7.判断集合是否为空 boolean empty = myList.isEmpty();//false //8.删除元素 myList.remove(b);
//autoboxing:不必把primitive主数据类型与对象分得那么清楚
public void doNumsNewWay(){
ArrayList l = new ArrayList();
l.add(3);
int num = l.get(0);
}
--------------
Integer i =new Integer(42);
i++;
---------------
//将primitive主数据类型值转换成String
double d = 45.5;
String b = "" + d;
double d = 45.5;
String b = Double.toString(d);
ArrayList与一般数组比较
- 一般数组在创建时就必须指定大小new String[2] ArrayList无需指定大小new ArrayList()一般数组存放对象必须放在指定位置myList[1]=b; ArrayList直接添加myList.add(b)
- Dog myDog 要求Java虚拟机分配空间给引用变量new Dog( ); 要求Java虚拟机分配堆空间给新建立的Dog对象= 将新的Dog赋值给myDog这个引用变量
- private String name;将name属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。this(); this(t); 调用无参,调用一个有参构造方法;this()类型调用构造方法只能在构造方法的首行。
class Student {
private int age;
//get、set方法 alt+insert
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
public class Demo01 {
public static void main(String[] args) {
Student s1 = new Student();
s1.setAge(21);
System.out.println(s1.getAge());
}
}
------------------------
public class Demo01 {
public Demo01(){//构造参数没有返回值
System.out.println("*************");
}
public static void main(String[] args) {
Demo01 demo01 = null;//声明对象不调用构造
demo01 = new Demo01();//实例化对象调用构造
}
Static
- 如果类中的某个属性希望公开就加上staticstatic定义的方法可以用类名直接调用static方法不能直接访问非static属性或方法,只能调用static属性或方法,需要new调用别的属性非static方法可以访问static的属性或方法,不受任何的限制。不保存普通属性时定义static方法。不开辟堆内存保存属性内容
class BOOK{
private String title;
private double price;//普通属性
static String pub ="清华大学出版社";//定义一个描述出版社信息的属性,为操作方便,暂不封装
public Book(String title,double price) {
this.title= title ;
this.price = price ;
}
-----
Book book = new Book();
book.pub = "齐鲁师范学院"//修改一个属性的内容
Book.pub = "齐鲁师范学院"//static不用实例化也可以调用
代码块
public class Demo04 {
public static void main(String[] args) {
{//普通代码块
int num = 10;//局部变量
System.out.println(num);
}
int num = 100;//全局变量
System.out.println(num);
}
}
class Demo05{
public Demo05() {
System.out.println("A");
}
{//在类中,构造块
System.out.println("B");
}
}
public class TestDemo05 {
public static void main(String[] args) {
new Demo05();
new Demo05();
//B
//A,构造块优先与构造方法,无视书写位置
}
}
class Demo06{
static String msg;
public Demo06() {
System.out.println("A");
}
{
System.out.println("B");
}
static {//静态代码块,随着类只执行一次
msg = "Hello".substring(0,2);//利用静态代码块static属性初始化
System.out.println("C");
}
}
class TestDemo06 {
public static void main(String[] args) {
new Demo06();//C B A
new Demo06();//B A
//System.out.println(new Demo06().msg);
System.out.println(Demo06.msg);//He
}
}
内部类
class Demo07{
private String msg ="A";
//private class In{}
//由于存在private声明,所以Inner类只能在Outer类的内部使用
//此时无法在外部实例化Inner类对象,而这个内部类只能为Outer一个类服务。
class In{//内部类
public void put(){
System.out.println(Demo07.this.msg);//外部类.this = 外部类当前对象
}
}
}
public class TextDemo07 {
public static void main(String[] args) {
Demo07.In in = new Demo07().new In();//实例化内部类对象
in.put();
}
}
class Out{
private static String msg = "A";
static class In{//static定义的内部类=外部类
public void put(){
System.out.println(Out.msg);//直接访问static属性
}
}
}
public class TestDemo08 {
public static void main(String[] args) {
Out.In in = new Out.In();//实例化“外部类”对象
in.put();
}
}
class out{
private String msg = "A";
//1.7public void fun(final int num){final double score = 99.9;}
public void fun(int num) {//外部类普通方法
double score = 99.9;//方法变量
class In {//方法中定义的内部类
public void print(){
System.out.println("属性"+out.this.msg);
System.out.println("方法参数"+num);
System.out.println("方法变量"+score);
}
}
new In().print();//内部类实例化对象调用print()输出
}
}
public class TestDemo09 {
public static void main(String[] args) {
new out().fun(100);
}
}
继承
- 实例化子类对象,它会默认先执行父类构造父类中提供无参构造方法时,是否编写“super()” 没有区别。父类中没有无参构造方法,必须使用super()调用父类指定参数的构造方法子类会继承public实例和方法,不会继承privateJava 不支持多继承,但支持多重继承final 可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写
- 即外壳不变,核心重写!需要有继承关系,子类重写父类的方法(方法必须一致,方法体不同)方法名必须相同,参数列表必须相同修饰符的范围可以扩大但不能缩小:public>protected>default>private要想调用父类中被重写的方法,则必须使用关键字 super
class Demo01{
public void print(){
System.out.println("A");
}
}
class B extends Demo01{
public void print(){//覆写
super.print();//调用父类方法
System.out.println("B");
}
}
public class TestDemo01 {
public static void main(String[] args) {
B b = new B();
b.print();
}
}
-------------------------
class A2{
String a = "www";
}
class B2 extends A2{
int a = 10;//属性覆盖
public void print(){
System.out.println(super.a);
System.out.println(this.a);
}
}
public class TestDemo03 {
public static void main(String[] args) {
B2 b2 = new B2();
b2.print();
}
}
重载overload
返回类型可以不同,参数列表必须修改
public int add(int a,int b){}
public double add(double a,double b){}
public void setID(String id){}
public void setID(int numid){}
多态
- 多态是方法的多态,属性没有多态ClassCastException父类子类转换异常必须有继承关系,方法要重写,父类引用指向子类对象 Fathor f1 = new Son();static,final,private不能被重写子类转父类,向上转型;父类转子类,向下强制转多态实现于:重写、接口、抽象类和抽象方法向上转型:子类对象变为父类对象,格式:A a = new B();,自动转换。a.print()调用子类覆写方法向下转型:父类对象变为子类对象,格式:B b = (B) a;,强制转换;必须得先向上转型才能向下转型。b.print()调用子类覆写方法
ArrayList抽象类myDogArrayList = new ArrayList ();//保存Dog的ArrayList Dog aDog = new Dog();//新建一个Dog myDogArrayList.add(aDog);//装到ArrayList中 Dog d = myDogArrayList.get(0);//将Dog赋值给新的引用变量 ------------------------------------------------ Object o = al.get(index); Dog d = (Dog) o;//将类型转换为Dog d.wang; ------------------------------------------------ if(o instanceof Dog){ Dog d = (Dog) o;//若是类型转换错误,则ClassCastException }
● 抽象类必须有子类
● abstract 抽象类,单继承,可以有方法体
● 不能new,只能靠子类去实现
● abstract public class A extends a{ } A不能被new了
● 抽象的类代表此类必须要被exends
● interface 定义的关键字,接口都需要有实现类,接口中的所有定义都是隐式public abstract
● 实现了接口的类,就需要重写接口中的方法
● 接口不能用于实例化对象。
● 接口没有构造方法。
● 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
● 接口不能包含成员变量,除了 static 和 final 变量。
● 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
● 接口支持多继承。
● 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
● 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
● 接口中的方法都是公有的。
abstract public class Canine extends Animal{
public void roam(){}
}
----------------------------------------
public class MakeCanine{
public void go(){
Canine c;
c = new Dog();//这是可以的,可以赋值子类对象给父类的引用,即使父类是抽象的
c = new Canine();//X!
c.roam;
}
}
抽象方法
● 继承的子类必须实现抽象类的抽象方法
● 继承抽象方法的子类必须重写该方法。除非该子类也是抽象类
● 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
● public abstract void 方法名();分号结束
● 如果一个类包含抽象方法,那么该类必须是抽象类
● 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法
public abstract class Employee{
private String name;
private String address;
private int number;
public abstract double computePay();
}
---------------------------------
public class Salary extends Employee{
private double salary;
public double computePay(){
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
abstract class Employee
{
private String name;
private String address;
private int number;
public void print(){
//普通方法不用覆写
}
public abstract double computePay();
}
class Salary extends Employee
{
private double salary;
public double computePay(){
System.out.println("1");
return salary/52;
}
}
public class TestDemo04 {
public static void main(String[] args) {
Employee employee = new Salary();
employee.computePay();//调用子类覆写方法
}
}
接口
interface A5{
public static final String MSG = "AA";//全局常量
public abstract void print();//定义抽象方法
}
interface B5{
public abstract void get();//定义抽象方法
}
class X implements A5,B5{
@Override
public void print() {//覆写抽象方法
System.out.println("A5");
}
@Override
public void get() {//覆写抽象方法
System.out.println("B5");
}
}
public class TestDemo05 {
public static void main(String[] args) {
X x = new X();//此时X类是A和B两个接口的子类,所以此类对象可以同时实现两个接口的向上转型
A5 a5 = x;
B5 b5 = x;
a5.print();//调用覆写方法
b5.get();
System.out.println(A5.MSG);//直接访问全局变量
}
}
//Sports.java
public interface Sports{
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
// Football.java 实现Football接口的类需要实现五个方法,其中两个来自于Sports接口。
public interface Football extends Sports{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
// Hockey.java 实现Hockey接口的类(必)需要实现六个方法。
public interface Hockey extends Sports
{
public void homeGoalScored();
public void visitingGoalScored();
public void endOfPeriod(int period);
public void overtimePeriod(int ot);
}
匿名对象
class Demo03{
private String a1;
private int b1;
public Demo03(String a,int b){
a1 = a;
b1 = b;
}
public void put(){
System.out.println(a1+b1);
}
}
public class TestDemo03 {
public static void main(String[] args) {
new Demo03("wahaha",66).put();//匿名对象,使用一次后被GC回收
}
}
package com.liu.java01;
public interface Nose {
public int iMethod();
}
------------------------
package com.liu.java01;
abstract class Picasso implements Nose{//抽象类实现接口不会强制实现方法
@Override
public int iMethod() {
return 7;
}
}
-----------------------
package com.liu.java01;
public class Clowns extends Picasso{
}
-----------------------
package com.liu.java01;
public class Acts extends Picasso{//不强制
@Override
public int iMethod() {
return 5;
}
}
----------------------
package com.liu.java01;
public class Of76 extends Clowns{
public static void main(String[] args) {
Nose[] i = new Nose[3];
i[0] = new Acts();
i[1] = new Clowns();
i[2] = new Of76();
for (int j = 0; j < i.length; j++) {
System.out.println(i[j].iMethod()+" "+i[j].getClass());
}
}
}
------------------------
// 5 class com.liu.java01.Acts
// 7 class com.liu.java01.Clowns
// 7 class com.liu.java01.Of76
匿名内部类简化类
interface Message{
public void print();
}
public class TestDemo07 {
public static void main(String[] args) {
fun(new Message(){//直接实例化接口对象
public void print(){//匿名内部类中覆写print()方法
System.out.println("A");
}
});//传递匿名内部类实例化
}
public static void fun(Message msg){//接收接口对象
msg.print();
}
}
异常
public class Demo01 {
public static void main(String[] args) {
int a = 1;
int b = 0;
//System.out.println(a/b);
//ctrl+alt+t
try {
System.out.println(a/b);
} catch (Exception e) {
e.printStackTrace();//打印错误的栈信息
} finally {
//不管有没有异常都执行
}
}
}
//如果try块失败了,流程转移到catch,catch完成转移到finally
多重异常
class ll{
public void do() throws P,L{}
}
.........................................................................................
public class Ff{
public void go(){
ll ll = new ll();
try{
ll.do();
}catch(P pex){
}catch(L lex){
}
}}
自定义异常类
● 如果希望写一个检查性异常类,则需要继承 Exception 类。
● 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
// 文件名InsufficientFundsException.java
import java.io.*;
//自定义异常类,继承Exception类
public class InsufficientFundsException extends Exception
{
//此处的amount用来储存当出现异常(取出钱多于余额时)所缺乏的钱
private double amount;
public InsufficientFundsException(double amount)
{
this.amount = amount;
}
public double getAmount()
{
return amount;
}
}
GUI和Swing略
多线程
自定义一个线程
- 第一种方法
//自定义线程继承Thread类
public class TestThread1 extends Thread{
//重写run方法
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println("呀"+i);
}
}
public static void main(String[] args) {
//主线程,创建一个线程对象
TestThread1 t = new TestThread1();
//调用start()方法开启线程
t.start();
for (int i = 0; i < 200; i++) {
System.out.println("啊"+i);
}
}
}
- 第二种方法
public class TestThread3 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("呀"+i);
}
}
public static void main(String[] args) {
//主线程,创建一个线程对象
TestThread3 t = new TestThread3();
//调用start()方法开启线程
//Thread thread = new Thread(t);
//thread.start();
new Thread(t).start();
for (int i = 0; i < 200; i++) {
System.out.println("啊"+i);
}
}
}
- 第三种方法
class x implements Callable网图下载{//1.实现Callable接口,并加一个返回值 //2.重写call方法 //3.线程池 //4.启动 }
下载导入commons-io-2.11.0,com下新建lib文件夹,右键添加到库
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class TestThread02 extends Thread{
private String url;//保存
private String name;
public TestThread02( String url,String name){
this.url = url;
this.name = name;
}
public void run(){
WebDownloader xiazai = new WebDownloader();
xiazai.downloader(url,name);
System.out.println("下载了图片"+name);
}
public static void main(String[] args) {
TestThread02 t1 = new TestThread02("https://pic.ntimg.cn/20120814/3173351_101349962000_2.jpg","1.jpg");
TestThread02 t2 = new TestThread02("https://pic.ntimg.cn/20120814/3173351_103505495000_2.jpg","2.jpg");
TestThread02 t3 = new TestThread02("https://pic.ntimg.cn/20120814/3173351_101349509000_2.jpg","3.jpg");
t1.start();
t2.start();
t3.start();
//new Thread(t1).start();
}
}
//下载器
class WebDownloader{
//自定义下载方法
public void downloader(String url,String name){
try {
//把一个url变成文件
FileUtils.copyURLToFile((new URL(url)),new File(name));
} catch (IOException e) {
e.printStackTrace();
}
}
}
并发问题
public class TestThread1 implements Runnable{
private int tickNums = 10;
@Override
public void run() {
while (true){
if (tickNums<=0)break;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//获取当前线程的名字Thread.currentThread().getName()
System.out.println(Thread.currentThread().getName()+"拿到了第"+tickNums+"票");
tickNums--;
}
}
public static void main(String[] args) {
TestThread1 t = new TestThread1();
//把线程丢进来并起名字
new Thread(t,"小明").start();
new Thread(t,"小黄").start();
new Thread(t,"小张").start();
new Thread(t,"小啊giao").start();
}
}
lambda表达式
一个接口里面如果只有一个抽象方法,那么就是一个函数式接口,可以用lambda创建该接口的对象
public class Testlambda1 {
//3.静态内部类
static class love2 implements Ilove{
public void f(){
System.out.println("我爱你2");
};
}
public static void main(String[] args) {
Ilove ilove = new love();
ilove.f();
ilove = new love2();
ilove.f();
//4.局部内部类
class love3 implements Ilove{
public void f(){
System.out.println("我爱你3");
};
}
ilove = new love3();
ilove.f();
//5.匿名内部类,没有类的名称,必须借助接口或父类
ilove = new Ilove() {
@Override
public void f() {
System.out.println("我爱你4");
}
};
ilove.f();
//6.用lambda简化,只留下了匿名内部类的方法括号()及箭头和方法体
ilove = ()->{
System.out.println("我爱你5");
};
ilove.f();
}
}
//1.定义一个函数式接口
interface Ilove{
void f();
}
//2.实现类
class love implements Ilove{
public void f(){
System.out.println("我爱你1");
};
}
package com.liu.java01;
public class Testlambda1 {
public static void main(String[] args) {
//2.用lambda简化,只留下了匿名内部类的方法括号()及箭头和方法体
Ilove ilove = ()->{
System.out.println("我爱你5");
};
ilove.f();
}
}
//1.定义一个函数式接口
interface Ilove{
void f();
}
线程休眠sleep
//模拟倒计时
public class TestStop2 {
public static void main(String[] args) {
try {
tendown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void tendown() throws InterruptedException {
int num = 10;
while (true){
Thread.sleep(1000);//!!
System.out.println(num--);
if (num<0)break;
}
}
}
礼让yield
public class TsetYied1 {
public static void main(String[] args) {
Yield yied1 = new Yield();
new Thread(yied1,"a").start();
new Thread(yied1,"b").start();
}
}
class Yield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始");
Thread.yield();//礼让,看cpu有可能成功有可能失败
System.out.println(Thread.currentThread().getName()+"结束");
}
}
插队join
强制执行
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("VIP"+i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin join = new TestJoin();
Thread t = new Thread(join);
t.start();
for (int i = 0; i < 100; i++) {
if(i==30){
t.join();//插队,主线程跑到30时,run开始跑,跑完后主线程再跑
}
System.out.println("ZZZ"+i);
}
}
}
线程状态
public class TestState{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("/");
});
Thread.State state = thread.getState();
System.out.println(state);//NEW
thread.start();
state = thread.getState();
System.out.println(state);//RUN
while (state != Thread.State.TERMINATED){//线程终止
Thread.sleep(100);
state = thread.getState();
System.out.println(state);
}
}
}
线程的优先级
public class TestPriority {
public static void main(String[] args) {
priority p1 = new priority();
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p1);
Thread t3 = new Thread(p1);
Thread t4 = new Thread(p1);
Thread t5 = new Thread(p1);
//先设优先级,在启动
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(3);
t3.start();
t4.setPriority(8);
t4.start();
t5.setPriority(Thread.MAX_PRIORITY);
t5.start();
}
}
class priority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
守护线程
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true);//守护进程。默认false是用户线程,平时的线程都是用户线程
thread.start();
new Thread(you).start();
}
}
class God implements Runnable{
@Override
public void run() {
while (true)
System.out.println("守护");
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 300; i++) {
System.out.println("活着"+i);
}
System.out.println("死亡");
}
}
三大不安全案例
//不安全的买票
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket station = new BuyTicket();
new Thread(station,"我").start();
new Thread(station,"你").start();
new Thread(station,"黄牛").start();
}
}
class BuyTicket implements Runnable{
private int ticketNums = 10;
boolean flag = true;
@Override
public void run() {
while (flag){
try {
Buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void Buy() throws InterruptedException {
//判断是否有票
if(ticketNums<=0){
flag = false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
//不安全的取钱
public class UnsafeBank {
public static void main(String[] args) {
//账户
Account account = new Account(100,"建行");
Drawing you = new Drawing(account,50,"你");
Drawing girlFriend = new Drawing(account,100,"女朋友");
you.start();
girlFriend.start();
}
}
//账户
class Account{
int money;//余额
String name;//卡名
public Account(int money,String name){
this.money = money;
this.name = name;
}
}
//银行模拟取款
class Drawing extends Thread{
Account account;//账户
int drawingMoney;//取了多少钱
int nowMoney;//现在手里多少钱
public Drawing( Account account,int drawingMoney,String name){
super(name);
this.drawingMoney = drawingMoney;
this.account = account;
}
//取钱
@Override
public void run() {
//判断有没有钱
if(account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"没钱了取不了");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卡内余额 = 余额-取的钱
account.money = account.money - drawingMoney;
//手里的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name+"余额:"+account.money);
System.out.println(Thread.currentThread().getName()+"手里的钱"+nowMoney);
}
}
import java.util.ArrayList;
import java.util.List;
//线程的不安全性
public class UnsafeList {
public static void main(String[] args) {
List list = new ArrayList();
//CopyOnWriteArrayList list = new CopyOnWriteArrayList();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
同步方法及方法块
//synchronized同步方法,锁的是this
private synchronized void Buy() throws InterruptedException {
//判断是否有票
if(ticketNums<=0){
flag = false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
//取钱
@Override
//synchronized 默认锁的是同步块this.
public void run() {
//锁账户,锁的对象是变化的量,需要增删改的对象
synchronized (account){
//判断有没有钱
if(account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够取不了");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//卡内余额 = 余额-取的钱
account.money = account.money - drawingMoney;
//手里的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name+"余额:"+account.money);
System.out.println(Thread.currentThread().getName()+"手里的钱"+nowMoney);
}
}
for (int i = 0; i < 10000; i++) {
new Thread(()->{
synchronized (list){
list.add(Thread.currentThread().getName());
}
}).start();
Lock
死锁:多个线程互相抱着对方持有的资源,形成僵持
import java.util.concurrent.locks.ReentrantLock;
//lock只能锁代码块
public class TestLock {
public static void main(String[] args) {
Buyticket buyticket = new Buyticket();
new Thread(buyticket).start();
new Thread(buyticket).start();
new Thread(buyticket).start();
}
}
class Buyticket implements Runnable{
int ticketNums = 10;
//定义lock锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
lock.lock();//加锁
//try里面是保证线程安全的代码
try{if (ticketNums>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketNums--);
}else {
break;
}}finally {
lock.unlock();//解锁
//如果同步代码有异常,要将unlock()写入finally语句块
}
}
}
}
管程法
//测试:生产者消费者模型-->利用缓冲区解决:管程法
//生产者,消费者,产品,缓冲区
public class TestPC {
public static void main(String[] args) {
SysContainer sysContainer = new SysContainer();
new Productor(sysContainer).start();
new Consumer(sysContainer).start();
}
}
//生产者
class Productor extends Thread{
SysContainer container;
public Productor(SysContainer container){
this.container = container;
}
//生产
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Chicken(i));
System.out.println("生产了"+i+"只鸡");
}
}
}
//消费者
class Consumer extends Thread{
SysContainer container;
public Consumer(SysContainer container){
this.container = container;
}
//消费
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了"+container.pop().id+"只鸡");
container.push(new Chicken(i));
}
}
}
//产品
class Chicken{
int id;
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SysContainer {
//需要一个容器大小
Chicken[] chickens = new Chicken[10];
//容器计数器
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken) {
//如果容器满了,就需要等待消费
if (count == chickens.length) {
//通知消费者消费,生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没满,就要丢入产品
chickens[count] = chicken;
count++;
//可以通知消费者消费了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop() {
//判断能否消费
if(count == 0){
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果可以消费
count--;
Chicken chicken = chickens[count];
//吃完了,通知生产者生产
this.notifyAll();
return chicken;
}
}
信号灯法
通过标志位判断
public class TestPc2 {
public static void main(String[] args) {
Tv tv = new Tv();
new Player(tv).start();
new Watcher(tv).start();
}
}
class Player extends Thread{
Tv tv;
public Player(Tv tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if(i%2==0){
this.tv.play("快乐大本营播放中");
}else {
this.tv.play("抖音:记录美好生活");
}
}
}
}
class Watcher extends Thread{
Tv tv;
public Watcher(Tv tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
this.tv.watch();
}
}
}
class Tv{
String voice;//节目
boolean flag = true;
//表演
public synchronized void play(String voice){
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("演员表演了:"+voice);
//通知观众观看
this.notifyAll();//通知唤醒
this.voice = voice;
this.flag = !this.flag;
}
//观看
public synchronized void watch(){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观看了:"+voice);
//通知演员表演
this.notifyAll();//通知唤醒
this.flag = !this.flag;
}
}
线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestPool {
public static void main(String[] args) {
//1.创建服务,创建线程池
//newFixedThreadPool 参数为:线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
//2.执行
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//3.关闭链接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
网络编程
IP地址
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args) {
try {
//查询本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
InetAddress inetAddress2 = InetAddress.getByName("localhost");
InetAddress inetAddress3 = InetAddress.getLocalHost();
System.out.println(inetAddress1);
System.out.println(inetAddress2);
System.out.println(inetAddress3);
//查询网络ip地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress4);
//实用方法
System.out.println(inetAddress4.getCanonicalHostName());//规范的名字
System.out.println(inetAddress4.getAddress());//ip
System.out.println(inetAddress4.getHostName());//域名,或者自己电脑的名字
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
端口Port
公有端口:
● HTTP:80
● HTTPS:443
● FTP:21
● Telent:23
程序注册端口:
● Tomcat:8080
● MySQL:3306
● Oracle:1521
import java.net.InetSocketAddress;
public class TestSocketAddress {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
System.out.println(inetSocketAddress1);
System.out.println(inetSocketAddress2);
System.out.println(inetSocketAddress1.getAddress());
System.out.println(inetSocketAddress1.getHostName());//地址
System.out.println(inetSocketAddress1.getPort());//端口
}
}
通信协议
TCP
客户端:
- 连接服务器Socket发送消息
服务器:
- 建立服务的端口 ServerSocket等待用户的连接 accept接收用户的消息
//服务端,先启动服务端
public class TestClick {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.要有一个地址
serverSocket = new ServerSocket(9999);
//2.等待客户端连接起来
socket = serverSocket.accept();
//3.读取客户端的消息
is = socket.getInputStream();
//管道流
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭资源
if(baos != null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class TcpClientDemo01 {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
//1.要知道服务器的地址 端口号 连接到服务器
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
int port = 9999;
//2.创建一个Socket连接
socket = new Socket(serverIP,port);
//3.发送消息 IO流
os = socket.getOutputStream();
os.write("你好啊".getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
}finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
实现文件上传
public class TcpServerDemo02 {
public static void main(String[] args) throws Exception{
//1.创建服务
ServerSocket serverSocket = new ServerSocket(9000);
//2.监听客户端的连接
Socket socket = serverSocket.accept();
//3.获取输入流
InputStream is = socket.getInputStream();
//4.文件输出
FileOutputStream fos = new FileOutputStream(new File("xinwenjian.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
//通知客户端,接收完毕
OutputStream os = socket.getOutputStream();
os.write("我接受完了,你可以关闭了".getBytes());
//5.关闭流
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
public class TcpClientDemo02 {
public static void main(String[] args) throws Exception {
//1.连接服务器Socket
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
//2.创建一个输出流
OutputStream os = socket.getOutputStream();
//3.读取文件
FileInputStream fis = new FileInputStream(new File("1.jpg"));
//4.写入文件
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//通知服务器我已经结束
socket.shutdownOutput();//我已经传输完了
//接收信息
InputStream is = socket.getInputStream();
//String byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int len2;
while ((len2 = is.read()) != -1){
baos.write(buffer2,0,len2);
}
System.out.println(baos.toString());
//5.关闭流
baos.close();
is.close();
fis.close();
os.close();
socket.close();
}
}
UDP
像发短信:不用连接,但需要知道对方地址
//不需要连接服务器
public class Udpsend {
public static void main(String[] args) throws Exception {
//1.建立一个Socket
DatagramSocket socket = new DatagramSocket();
//2.准备数据
String msg = "HI";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9090;
//3.建个包,1数据,23数据的长度起始,45要发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
//4.发送包
socket.send(packet);
//5.关闭流,包不用关
socket.close();
}
}
public class Udpok {
public static void main(String[] args) throws Exception {
//1.开放端口
DatagramSocket socket = new DatagramSocket(9090);
//2.接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0,buffer.length);//接收
socket.receive(packet);//3.阻塞接收
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
//4.关闭连接
socket.close();
}
}
聊天实现
public class UdpSenderDemo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
//准备数据 控制台读取in
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0 ,datas.length,new InetSocketAddress("localhost",6666));
socket.send(packet);
if(data.equals("bye"))
break;
}
}
socket.close();
}
}
public class UdpReceiveDemo01 {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(6666);
while (true){
//准备接收数据
byte[] container = new byte[1024];//容器
DatagramPacket packet = new DatagramPacket(container, 0,container.length);
socket.receive(packet);
//断开连接
byte[] data = packet.getData();
String receiveData = new String(data,0, data.length);
System.out.println(receiveData);
if (receiveData.equals("bye")){
break;
}
}
socket.close();
}
}
聊天实现(多线程)
public class TalkSend implements Runnable{
DatagramSocket socket;
BufferedReader reader;
private int fromPort;
private int toPort;
private String toIP;
public TalkSend(int fromPort, int toPort, String toIP) {
this.fromPort = fromPort;
this.toPort = toPort;
this.toIP = toIP;
try {
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
String data = reader.readLine();
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0 ,datas.length,new InetSocketAddress(this.toIP,this.toPort));
socket.send(packet);
if(data.equals("bye")){
break;
}
}catch (Exception e){
e.printStackTrace();
}
}
socket.close();
}
}
public class TalkReceive implements Runnable{
DatagramSocket socket;
private int port;
private String msgFrom;
public TalkReceive(int port, String msgFrom) {
this.port = port;
this.msgFrom = msgFrom;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
//准备接收数据
byte[] container = new byte[1024];//容器
DatagramPacket packet = new DatagramPacket(container, 0,container.length);
socket.receive(packet);
//断开连接
byte[] data = packet.getData();
String receiveData = new String(data,0, data.length);
System.out.println(msgFrom+": "+receiveData);
if (receiveData.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
public class TalkStudent {
public static void main(String[] args) {
new Thread(new TalkSend(7777,9999,"localhost")).start();
new Thread(new TalkReceive(8888,"老师")).start();
}
}
public class TalkTeacher {
public static void main(String[] args) {
new Thread(new TalkSend(5555,8888,"localhost")).start();
new Thread(new TalkReceive(9999,"学生")).start();
}
}
URL
public class UrlDemo01 {
public static void main(String[] args) throws Exception{
URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=xiaoliu&password=123");
System.out.println(url.getProtocol());//协议
System.out.println(url.getHost());//主机ip
System.out.println(url.getPort());//端口
System.out.println(url.getPath());//文件
System.out.println(url.getFile());//全路径
System.out.println(url.getQuery());//参数
}
}
下载网络资源
Tomcat–>webapps–>lym bin–>startup.dat http://localhost:8080/lym/a.txt
public class UrlDown {
public static void main(String[] args) throws Exception {
//1.下载地址
URL url = new URL("http://127.0.0.1:8080/lym/a.txt");
//2.连接到这个资源 HTTP
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();//打开
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("a.txt");
byte[] buffer = new byte[1024];
int len;
while ((len=inputStream.read(buffer))!=-1){
fos.write(buffer,0,len);//写出这个数据
}
fos.close();
inputStream.close();
urlConnection.disconnect();//断开连接
}
}
注解与反射
元注解
//测试元注解
public class Test01 {
@MyAnnotation
public void test(){
}
}
//定义一个注解
//Target 表示我们的注解可以用在什么地方
@Target(value = {ElementType.ANNOTATION_TYPE,ElementType.METHOD})
//Retention 表示我们的注解在什么地方有效
@Retention(value = RetentionPolicy.RUNTIME)
//documented 表示是否将我们的注解生成在JavaDoc中
@documented
//Inherited说明子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}
自定义注解
public class Test02 {
//注解可以显示赋值,如果没有默认值,就必须给注解赋值
@MyAnnotation2(name = "小刘",id = 1)
public void test(){}
//当注解只有一个参数,可以定义为value,可以直接赋值
@MyAnnotation3("a")
public void test2(){}
}
//自定义注解(TYPE类)
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
//注解的参数:参数类型+参数名();
String name() default "";
int id();
int age() default -1;//默认值为-1表示不存在
String[] schools() default {"q","a"};
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String value();
}
反射
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的class
Class c1 = Class.forName("com.lym.www.User");
System.out.println(c1);
Class c2 = Class.forName("com.lym.www.User");
//一个类在内存中只有一个Class对象
//一个类被加载后,类的整个结构都会封装在Class对象中
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
}
}
//实体类:pojo,entity
class User{
private String name;
private int id;
private int age;
public User(){
}
public User(String name,int id,int age){
this.age = age;
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", id=" + id +
", age=" + age +
'}';
}
}
Class类
得到Class类的方法
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是"+person.name);
//方法1:通过对象方式获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//2.forName获得
Class c2 = Class.forName("com.lym.www.Student");
System.out.println(c2.hashCode());
//3.通过 类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());
//4.基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4);
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person(){}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
'}';
}
}
class Student extends Person{
public Student() {
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher() {
this.name = "老师";
}
}
所有类型的Class对象
import java.lang.annotation.ElementType;
public class Test05 {
public static void main(String[] args) {
Class c1 = Object.class;//类
Class c2 = Comparable.class;//接口
Class c3 = String[].class;//一维数组
Class c4 = int[][].class;//二维数组
Class c5 = Override.class;//注解
Class c6 = ElementType.class;//枚举
Class c7 = Integer.class;//基本数据类型
Class c8 = void.class;//void
Class c9 = Class.class;//Class
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
}
}
分析类初始化
//分析类初始化
public class Test06 {
static {
System.out.println("main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.主动引用
Son son = new Son();
//2.反射也会产生主动引用
Class.forName("com.lym.www.Son");
//3.不会产生类的引用的方法
System.out.println(Son.b);//子类调用父类的静态对象
Son[] array = new Son[5];//数组也不会
System.out.println(Son.M);//调用常量也不会加载别的类
}
}
class Father{
static int b = 2;
static {
System.out.println("父类被加载");
}
}
class Son extends Father{
static {
System.out.println("子类被加载");
}
static int m = 100;
static final int M = 1;
}
类加载器
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类的加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//获取系统类加载器的父类加载器-->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//获取扩展类加载器的父类加载器-->根加载器(C/C++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("com.lym.o821.Test01").getClassLoader();
System.out.println(classLoader);
//测试JDK内置的类是谁加载的
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//如何获得系统类加载器可以加载的路径
System.out.println(System.getProperty("java.class.path"));
}
}
获取类运行时结构
public class Test02 {
public static void main(String[] args) throws Exception {
Class c1 ;
//Class c1 = Class.forName("com.lym.o821.User");
//通过反射
User user = new User();
c1 = user.getClass();
//获得类的名字
System.out.println(c1.getName());//获得包名+类名
System.out.println(c1.getSimpleName());//获得类名
//获得类的属性
System.out.println("--------------------------------");
Field[] fields = c1.getFields();//只能找到public属性
fields = c1.getDeclaredFields();//找到全部的属性
//files.for
for (Field field: fields) {
System.out.println(field);
}
//获得指定属性的值
Field name = c1.getDeclaredField("name");
System.out.println(name);
//获得类的方法
System.out.println("--------------------------------");
Method[] methods = c1.getMethods();//获得本类及其父类的全部public方法
for (Method method : methods) {
System.out.println("正常的:"+method);
}
methods = c1.getDeclaredMethods();//获得本类的所有方法
for (Method method : methods) {
System.out.println("getDeclaredMethods:"+method);
}
//获得指定方法。重载
System.out.println("--------------------------------");
Class[] parameterTypes;
Method getName = c1.getMethod("getName",null);
Method setName = c1.getMethod("setName",String.class);
System.out.println(getName);
System.out.println(setName);
//获得构造器
System.out.println("--------------------------------");
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println("#"+constructor);
}
//获得指定的构造器
Constructor constructor2 = c1.getDeclaredConstructor(String.class,int.class,int.class);
System.out.println("指定"+constructor2);
}
}
动态创建对象执行方法
创建类的对象:调用Class对象的newInstance()方法
● 类必须有一个无参数的构造器
● 类的构造器的访问权限需要足够
class User{
public User() {
System.out.println("无参构造器");
}
@Override
public String toString(){
return "阿巴阿巴";
}
}
//构造一个对象
public class TestDemo11 {
public static void main(String[] args) throws Exception {
//设置要操作对象的类名称
Class> cls = Class.forName("com.lym.o817.User");
Object obj = cls.newInstance();//相当于使用new调用无参构造器
User user = (User) obj;//向下转型
System.out.println(user);
}
}
class User{
private String name;
private int age;
public User() {
System.out.println("无参构造器");
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString(){
return "名字"+this.name+"年龄"+this.age;
}
}
//通过构造器创建对象
public class TestDemo11 {
public static void main(String[] args) throws Exception {
//设置要操作对象的类名称
Class> cls = Class.forName("com.lym.o817.User");
//明确地找到Book类中两个参数的构造
Constructor> con = cls.getConstructor(String.class,int.class);
Object obj = con.newInstance("小刘",22);//实例化对象,传递参数内容
System.out.println(obj);
}
}
class Book{
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
//通过反射调用普通方法
public class TestDemo12{
public static void main(String[] args) throws Exception {
String filedName = "title";//要操作的成员名称
Class> cls = Class.forName("com.lym.o817.Book");//取得要操作类的反射对象
Object obj = cls.newInstance();//必须实例化对象
//取得类中的setTitle()方法,参数类型为String
Method setMet = cls.getMethod("set"+initcap(filedName), String.class);
//通过反射获取一个方法
Method setMet = cls.geDeclaredMethod("setName", String.class);
//取得类中的getTitle()方法,不接收参数且无返回值类型声明
Method getMet = cls.getMethod("get"+initcap(filedName));
setMet.invoke(obj,"JAVA开发");//Book类对象.setTitle("JAVA开发")
System.out.println(getMet.invoke(obj));//Book类对象.getTitle()
}
public static String initcap(String str){
return str.substring(0,1).toUpperCase()+str.substring(1);
}
}
class Book{
private String title;
}
//通过反射操作属性
public class TestDemo12{
public static void main(String[] args) throws Exception {
Class> cls = Class.forName("com.lym.o817.Book");
Object obj = cls.newInstance();
Field titleFiled = cls.getDeclaredField("title");//取得类中的title属性
titleFiled.setAccessible(true);//取消封装
titleFiled.set(obj,"Java开发");//Book类对象.title = "数据"
System.out.println(titleFiled.get(obj));//Book类对象.title
}
}
分析性能
public class Test01 {
//普通方式调用
public static void test01(){
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方法执行10亿次"+(endTime-startTime)+"ms");
}
//反射方式
public static void test02() throws Exception {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
getName.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式执行10亿次"+(endTime-startTime)+"ms");
}
//关闭反射方式
public static void test03() throws Exception {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
getName.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("关闭反射方式执行10亿次"+(endTime-startTime)+"ms");
}
public static void main(String[] args) throws Exception {
test01();
test02();
test03();
}
}
//实体类:pojo,entity
class User{
private String name;
private int id;
private int age;
public User(){
}
public User(String name,int id,int age){
this.age = age;
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", id=" + id +
", age=" + age +
'}';
}
}
获取泛型信息
//通过反射获取泛型
public class Test02 {
public void test01(Map map, List list){
System.out.println("01");
}
public Map test02(){
System.out.println("02");
return null;
}
public static void main(String[] args) throws Exception {
Method method = Test02.class.getDeclaredMethod("test01", Map.class, List.class);
//获得泛型的参数类型
Type[] a = method.getGenericParameterTypes();
for (Type type : a) {
System.out.println("#"+type);
//得到里面的类型,判断是否是结构化类型
if(type instanceof ParameterizedType){
//强转获得信息
Type[] b = ((ParameterizedType)type).getActualTypeArguments();
for (Type type1 : b) {
System.out.println(type1);
}
}
}
}
}
获取注解信息
//反射操作注解
public class Test03 {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("com.lym.o822.Student");
//通过反射获得注解
Annotation[] annotation = c1.getAnnotations();//返回全部注解
for (Annotation annotation1 : annotation) {
System.out.println(annotation1);
}
//获得注解value的值
Tableliu t1 = (Tableliu)c1.getAnnotation(Tableliu.class);
String value1 = t1.value();
System.out.println(value1);
//获得类指定的注解
Field field = c1.getDeclaredField("id");
Filedliu f1 = field.getAnnotation(Filedliu.class);
System.out.println(f1.tName());
System.out.println(f1.length());
System.out.println(f1.type());
}
}
@Tableliu("DB")
class Student{
@Filedliu(tName = "db_name",type ="varchar",length = 5)
private String name;
@Filedliu(tName = "db_id",type ="int",length = 12)
private int id;
@Filedliu(tName = "db_age",type ="int",length = 3)
private int age;
public Student() {
}
public Student(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", id=" + id +
", age=" + age +
'}';
}
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tableliu{
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Filedliu{
String tName();
String type();
int length();
}
集合
● ArrayList songList = new ArrayList();
● TreeSet 以有序状态保持并可防止重复
● HashMap 可用成对的name/value来保存与取出
● linkedList 针对经常插入或删除中间元素所设计的高效率集合
● HashSet 防止重复的集合,可快速的寻找相符的元素
● linkedHashMap 类似HashMap,但可记住元素插入的顺序,也可设定成依照元素上次存取的先后来排序
//1.创建被泛型化类(例如ArrayList)的实例 new ArrayList引出泛型() //2.声明与指定泛型类型的变量 List songList = new ArrayList () //3.声明、取用泛型类型的方法 void foo(List list) x.foo(songList)
class Point {//定义坐标
private Object x;
private Object y;
public Object getX() {
return x;
}
public void setX(Object x) {
this.x = x;
}
public Object getY() {
return y;
}
public void setY(Object y) {
this.y = y;
}
}
class TestDemo{
public static void main(String[] args) {
//定义数据
Point p = new Point();
p.setX(10);// p.setX("aaaaaa");
p.setY(20);
//取出数据
int x = (Integer) p.getX();//String x = (String) p.getX();
int y = (Integer) p.getY();
System.out.println("X:"+x+",Y"+y);
}
}
使用泛型修改Point类
class Point通配符{//Type T是一个类型标记 private T x;//此属性的类型不知道,有Point类使用时动态决定 private T y; public T getX() { return x; } public void setX(T x) { this.x = x; } public T getY() { return y; } public void setY(T y) { this.y = y; } } class TestDemo { public static void main(String[] args) { //定义数据 Point p = new Point ();//1.7后可以省略 Point p = new Point<>(); p.setX("aaaaaa"); p.setY("20aaa"); //取出数据 String x = p.getX(); String y = p.getY(); System.out.println("X:" + x + ",Y" + y); } }
class Message{ private T msg; public T getMsg() { return msg; } public void setMsg(T msg) { this.msg = msg; } } class TextDemo01{ public static void main(String[] args) { Message m1 = new Message<>(); Message m2 = new Message<>(); m1.setMsg(100); m2.setMsg("wwwww"); fun(m1);//引用传递 fun(m2); } public static void fun(Message> temp){//不能设置但可以取出 System.out.println(temp.getMsg()); } }
● “?extend 类” :设置泛型上限。声明和方法参数上使用
● “?extend Number” :可以设置Number或者Number的子类(Integer、Double…)
● “?super 类” :设置泛型下限。方法参数上使用
● “?super String” :只能设置String或它的父类Object
class Message{ private T msg; public T getMsg() { return msg; } public void setMsg(T msg) { this.msg = msg; } } class TextDemo01{ public static void main(String[] args) { Message m1 = new Message<>(); m1.setMsg(100); fun(m1);//引用传递 } public static void fun(Message extends Number> temp){//不能设置但可以取出 System.out.println(temp.getMsg()); } }
class Message泛型接口{ private T msg; public T getMsg() { return msg; } public void setMsg(T msg) { this.msg = msg; } } class TextDemo01{ public static void main(String[] args) { Message m1 = new Message<>(); m1.setMsg("sssssss"); fun(m1);//引用传递 } public static void fun(Message super String> temp){//不能设置但可以取出 System.out.println(temp.getMsg()); } }
//实现方式一:在子类继续设置泛型标记。 interface IMessage{//定义泛型接口 public void print(T t); } class MessageImpl implements IMessage {//在子类继续设置泛型,此泛型也作为接口中的泛型类型 @Override public void print(T t) { System.out.println(t); } } class TextDemo01{ public static void main(String[] args) { IMessage msg = new MessageImpl<>(); msg.print("ssss"); } }
//实现方式二:在子类不设置泛型,而为父接口明确地定义一个泛型类型。 interface IMessage泛型方法{//定义泛型接口 public void print(T t); } class MessageImpl implements IMessage {//子类为父接口设置具体泛型类型 @Override public void print(String t) { System.out.println(t); } } class TextDemo01{ public static void main(String[] args) { IMessage msg = new MessageImpl(); msg.print("ssss"); } }
class TextDemo01 {
public static void main(String[] args) {
String str = fun("qqqqqqqqqqqq");
System.out.println(str.length());
}
//T的类型由传入的参数决定
public static T fun(T t) {
return t;
}
}



