JavaSE
继承
格式
class A{}
class B extends A{}
特点:
子类可以拥有父类中的内容
利弊
利
提高了代码的复用性,维护性
弊
子类随着父类变化,削弱了子类的独立性
继承注意事项
- 只能单继承,可以多层继承
在子类方法中访问一个变量
- 子类局部范围找
- 子类成员范围找
- 父类成员范围找
super
super在子类中使用,代指父类对象的引用 父类存储空间的标识
this指本类对象的引用
构造方法
子类的构造方法
默认存在super(); 访问父类的构造方法 因此若父类不存在无参构造方法,会报错。
###此时推荐自己给出无参构造方法
public Zi(){
super();
}
子类中访问成员方法
- 子类范围中找
- 父类成员范围中找
- 如果找不到就报错
方法重写
子类中出现了和父类中一摸一样的方法声明
可加上@Override检查方法重写声明的正确性
注意事项
- 父类中私有方法,子类不能重写(加overrider会报错)因为私有成员,子类不能继承
- 子类方法访问权限不能更低(public > 默认 > 私有)
包
包其实就是文件夹
作用:对类进行分类管理
格式:package 包名(多级包用.分级)
命令行执行代码,存在包名,需要加包名执行
可以手动建包,也可以自动
执行指令
java com.vashon.demo
导入包
格式:import java.utils.Scanner
修饰符
权限修饰符
修饰符 | 同一个类 | 同一个包中子类无关类 | 不同包子类 | 不同包无关类 |
---|---|---|---|---|
private | √ | |||
默认 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
状态修饰符
final 最终的意思
- 被修饰的方法不能重写(最终方法)
- 被修饰的变量不能再次被赋值(常量)
- 被修饰的类不能被继承(最终类)
static 共享
被所有对象共享的成员对象
class Student{
public static String gongxiang;
}
特点:
1. 被所有对象共享
2. 可以通过类名(推荐)调用,也可以通过对象调用
访问特点:
1. 非静态方法能访问类中所有成员变量、成员方法
2. 静态方法,只能访问静态的成员变量和静态成员方法
多态
前提
有继承关系
有方法重写
用父类引用指向子类对象
Fu fu = new Zi();
利弊
利
- 提高程序的扩展性
弊
- 不能访问子类特有的功能
多态的转型
向上转型
子类转父类
Fu fu = new Zi();
向下转型
父类转子类
Fu fu = new Zi();
Zi zi = (Zi)fu;
抽象类
概述
一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
抽象类名作为参数/返回值
可使用抽象类的子类做放返回值
接口
接口中不能有构造方法
只能有抽象方法
Jumpping.java
public interface Jumpping {
public void jump();
}
JumppingOperator.java
public class JumppingOperator {
public void method(Jumpping jumpping){
jumpping.jump();
}
}
Dog.java
public class Dog implements Jumpping{
@Override
public void jump() {
System.out.println("狗狗跳高");
}
}
JumppingDemo.java
public class JumppingDemo {
public static void main(String[] args) {
Dog dog = new Dog();
JumppingOperator jumppingOperator = new JumppingOperator();
jumppingOperator.method(dog);
}
}
接口成员特点
成员变量默认public static final
方法只能是抽象方法
类、接口的关系
类和类
只能单继承
类和接口
继承一个类同时可以接口多实现
接口和接口
可以单、多继承
抽象类和接口的区别
成员区别
- 抽象类 有构造方法,有抽象方法,非抽象方法
- 接口 常量 抽象方法
关系区别
- 类与类 单继承
- 类与接口 多实现
- 接口与接口 多实现
设计理念
- 抽象类 对类抽象
- 接口 对行为抽象
内部类
访问特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
public class Outer {
public class Inner{
}
public void show(){
Inner inner = new Inner();
}
}
局部内部类
-
局部内部类是在方法中定义的类,所以外界无法直接使用,需要在方法内部创建对象并使用
-
改类可以直接访问外部类的成员,也可以直接访问方法内的局部变量
匿名内部类
本质
一个继承了某个类或者实现了某个接口的子类匿名对象
常用API
Math
Math.abs(int a) //返回绝对值
Math.ceil(double a) //返回double 顶
Math.floor(double a) //返回double 底
Math.max(int a, int b)
Math.min(int a, int b)
Math.pow(double a, double b) //返回a的b次幂 double类型
Math.random() //返回double的正值
System
System.exit(0); //终止当前的虚拟机
System.currentTimeMillis(); //返回当前时间与1970.1.1午夜之间的差异,以毫秒为单位
Object
toString
默认
return getClass().getName() + "@" + Integer.toHexString(hashCode());
//类的全限定名称+@+哈希值
equals
需要重写
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
demo05 demo05 = (demo05) o;
return age == demo05.age;
}
Arrays
Arrays.toString();
int [] array = {1,2,3,4};
System.out.println(Arrays.toString(array));
[1, 2, 3, 4]
Arrays.sort(array); //升序排序
Date
构造方法
Date d = new Date(); //默认现在的时间 Mon Nov 16 20:46:10 CST 2020
long a = 1000*60*60*24;
a*=365;
Date d = new Date(a); //参数是距1970的毫秒数
常用方法
d.getTime();//距离1970的毫秒数
d.setTime(); //设置距离1970的毫秒数
SimpleDateFormat
构造方法
SimpleDateFormat sdf = new SimpleDateFormat();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
常用方法
Date -> String
String s = sdf.format(d);
String -> Date
Date d = sdf.parse(s);
Calendar
构造方法
Calendar c = Calendar.getInstance(); //多态形式
常用方法
c.get(Calendar.YEAR); //年
c.get(Calendar.MONTH + 1); //月
c.get(Calendar.DATE); //日
//设置年月日
c.set(2010,1,1);
c.add(Calendar.YEAR,-3) //相应字段 加减 此处年份-3
基本类型包装类
Integer
Integer.MAX_VALUE
Integer.MIN_VALUE
构造方法
Integer i = new Integer(100); //过时
Integer i = Integer.valueOf(100); //推荐
int -> String
1. String s = 1 + "";
2. String s = String.valueOf(1);
String -> int
1.
Integer i = Integer.valueOf(s);
int i2 = i.intValue();
2.
int i = Integer.parseInt("102");
自动拆箱、装箱
装箱
基本类型->包装类
Integer i = 100; //Integer i = Integer.valueOf(100);
拆箱
包装类->基本类型
i ++; // i = Integer.valueOf( i.intValue() + 1 );
异常
-
Throwable所有异常的超类
-
Exception和Error是其子类
Error:严重问题,不需要处理
Exception:称为异常类,它表示程序本身可以处理的问题
*RuntimeException:在编译期间是不检查的,出现问题后,需要修改代码
*非RuntimeException:编译期间就检查,否则编译不通过。
jvm默认处理方案
如果程序出现问题。jvm默认处理
- 把异常的名称、异常原因以及异常出现的位置等信息输出在控制台
- 程序停止执行
异常处理
try - catch
try{
}catch(异常类名 变量名){
异常处理代码;
}
执行流程
程序从try里面的代码开始执行
出现异常,会自动生成一个异常类对象,该异常对象将被提交给java运行时系统
当java运行时系统接收到异常对象时,会到catch中找找匹配的异常类,最后进行异常的处理
执行完毕后,程序还可以继续往下执行。
throws
throws 异常类名 //这个格式通常加在括号后面
编译时异常必须进行处理,解决方案,try...catch 或者throws
运行时异常可以不处理,出现问题后,回来修改代码
自定义异常
定义一个类继承exception
throws和throw的区别
throws
用在方法声明后面,跟的是异常类名
表示抛出异常,由该方法的调用者来处理
表示出现异常的一种可能性,并不一定会发生这些异常
throw
用在方法体内,跟的时是异常类名
表示抛出异常,由方法体内的语句处理
执行throw一定抛出某种异常
集合
单列集合Collection
可重复 List 实现列 ArrayList LinkedList
不可重复 Set 实现类 HashSet TreeSet
常用方法
collection.add(); //返回true
collection.clear(); //返回true
collection.isEmpty();
collection.size();
遍历
Iterator<String> it = c.iterator();
sout(it.next());
List
有序
可重复
可精确控制存放位置
ArrayList和LinkedList
前者,底层数据结构 数组,增删慢,查询快
后者,底层数据结构 链表,增删快,查询慢
LinkedList特有功能
addFirst(E e);
addLast(E e);
getFirst(E e);
getLast(E e);
removeFirst(E e);
removeLast(E e);
并发修改异常
在使用迭代器时,会判断预期修改次数和实际修改次数是否相等
而使用了add后会增加实际修改次数,不会增加预期修改次数
增强for循环
for(String s: list){
System.out.println(s);
}
//实现原理:使用迭代器
Set
特点:
不包含重复元素
哈希值
默认情况下,不同对象的哈希值是不同的,而重写hashCode()方法,可以实现让不同对象的哈希值相同
System.out.println("重地".hashCode());
System.out.println("通话".hashCode());
两者相同
Set如何保证元素不重复
先计算hash值
hash值相同再判断equals方法 不相等,则添加。相等,不添加进去
LinkedHashSet
保证了能预测的顺序
TreeSet
TreeSet特点:
元素有序:这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式,取决于构造方法
构造方法:
无参构造 存储的元素要实现Comparable<>
比较器 TreeSet t = new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student s1,Student s2){
int num = s1.getAge() - s2.getAge();
return num;
}
})
没有索引的方法, 所以不能使用普通for循环遍历
不包含重复的元素
双列集合Map
实现类
HashMap
Interface Map<K,V>
方法
Map<String,String> map = new HashMap<>();
map.put("滴滴","哒哒"); //添加元素
map.remove("滴滴"); //若存在滴滴,返回对应的value值,若不存在,返回null
map.containsKey("滴滴");//返回true/false
map.clear();
map.isEmpty(); //判断是否为空
//获取值
map.get("滴滴") //根据key获取value
Set<K> keySet = map.keySet(); //获得键的集合
Collection<V> values map.values(); //获得值的集合
遍历
Set<String> keySet = map.keySet(); //获得键的集合
for(String key: keySet){
String value = map.get(key);
System.out.println(key + "" + value);
}
Set<Map.Entry<K,V>> entrySet = map.entrySet(); //获得键值对
for(Map.Entry<K,V> me: entrySet){
K key = me.getKey();
}
HashMap
泛型
本质:参数化类型,就是说所操作的数据类型被指定为一个参数
将类型有原来的具体类型参数化,然后在使用/调用时传入具体的类型
Collection<String> c = new ArrayList<String>();
格式
泛型类
public class classDemo<T>{}
泛型方法
public <T>void show(T t){
}
泛型接口
public interface interfaceDemo<T>{ }
*类型通配符
通配符上限
<? extends 类型>
List<? extends Number> 表示Number或者其子类型
通配符下限
<? super 类型>
List<? super Number> 表示Number或者其子类型
可变参数
格式:public static int sum(int... a){
//这里的变量其实是一个可变参数,可变参数要放在最后
for(int i: a){
}
}
可变参数的使用
List<String> list = Arrays.asList("sf","sfd",...); //返回的list大小固定,不可添加删除
List<String> list = List.of("sf","sfd",...); //返回包含任意元素的不可变列表,不可添加删除
Set<String> set = Set.of("sf","sfd",...);//返回一个包含任意数量元素的不可变集合。 不能添加删除,不能有重复元素
Collections
List<Integer> list = new ArrayList<Integer>();
Collections.sort(list);
Collections.reverse(list);
Collections.shuffle(list); //元素顺序打乱
I/O流
File
构造方法
//文件和目录路径名的抽象表示
File f1 = new File("E:\\mulu\\1.txt"); //路径
File f2 = new File("E:\\mulu","1.txt"); //目录+文件名
File f3 = new File("E:\\mulu");
File f4 = new File(f3,"1.txt"); //路径+文件名
文件创建功能
File f1 = new File("E:\\mulu\\1.txt"); //路径
f1.createNeaFile();//如果文件不存在,创建文件并返回true,存在,返回false
File f2 = new File("E:\\mulu");
f2.mkdir();//创建单级目录
File f3 = new File("E:\\mulu\\muli2");
f3.mkdirs(); //创建多级目录
File类判断和获取功能
f.isDerectory(); //是否为目录
f.isFile(); //是否为文件
f.exists(); //File是否存在
f.getAbsolutePath(); //返回此抽象路径名表示的File的绝对路径
f.getPath(); //将此抽象路径名转换为路径名字符串
f.getName(); //表示的文件或目录名称
f.list(); //获得目录下的file的名字 String数组
f.listFiles(); //返回目录下的file组
File删除功能
//删文件
f.delete();
//删目录 得先删除里面的内容,再删除文件
f.delete();
遍历目录
public static void digui(File file){
if (file.isDirectory()){
System.out.println(file.getName());
File[] files = file.listFiles();
for (File f: files){
digui(f);
}
}else{
System.out.println(file.getName());
}
}
字节流
流的本质:数据传输
分类
按照数据流向:
输入流 读数据
输出流 写数据
按照数据类型:
字节流
字符流
一般按照数据类型分
字节流写数据
字节输入流超类 InputStream
字节输出流超类 OutputStream
FileOutputStream fos = new FileOutputStream("E:\\mulu\\1.txt");
FileOutputStream fos = new FileOutputStream("E:\\mulu\\1.txt",true) //追加;
//FileOutputStream fos = new FileOutputStream(new File("E:\\mulu\\1.txt"));
//做了3件事
//创建了文件,创建了字节输出流对象,让对象指向创建好的文件
fos.write(内容);
// byte[] b = "abcde".getBytes();
// fos.write(b);
fos.close();
换行
fos.write("\r\n".getBytes());
加入finally来释放资源
try{
}catch(){
}finally{
fos.close();
}
字节流读数据
FileInputStream fis = new FileInputStream("E:\\mulu\\1.txt");
byte[] bys = new byte[1024];
int by = fis.read(bys);
//读到文件尾,返回 -1
字节缓冲流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("..."));
bos.write("hello\r\n".getBytes());
bos.close();
字符流
字节流不能很好地处理中文
FileOutputStream fos = new FileOutputStream("E:\\mulu\\1.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
osw.write("didi");
FileInputStream fis = new FileInputStream("E:\\mulu\\1.txt");
InputStreamReader isr = new InputStreamReader(fis);
ch = isr.read();
字符流写数据
FileOutputStream fos = new FileOutputStream("E:\\mulu\\1.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
//1.写一个字符 write(int c)
osw.write(98);
//2.写一个字符数组 write(char[] cbuf)
char[] cbuf = {98,99,100};
osw.write(cbuf);
//3.写入字符数组一部分 write(char[] cbuf,int off,int len)
osw.write(cbuf,0,1);
//4.写入字符串
osw.write("didi");
//5.写入字符串一部分write(String s, int off, int len)
osw.write("didi",0,3)
osw.flush(); //将数据从缓冲区写入文件
osw.close(); //关闭流,关闭flush之前,会先调用flush
字符流读数据
FileInputStream fis = new FileInputStream("E:\\mulu\\1.txt");
InputStreamReader isr = new InputStreamReader(fis);
int ch;
while((ch = isr.read())!= -1){
sout((char) ch);
}
//一次读一个数组
char[] chs = new char[1024];
int len;
while((len = isr.read(chs))!=-1){
sout(new String(chs,0,len));
}
字符流读写java文件
File f = new File("E:\\Java\\javaSE\\java.txt");
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
File f2 = new File("E:\\Java\\javaSE\\java2.txt");
FileOutputStream fos = new FileOutputStream(f2);
OutputStreamWriter osw = new OutputStreamWriter(fos);
char[] chars = new char[1024];
int len;
while((len = isr.read(chars))!=-1){
osw.write(chars,0,len);
}
isr.close();
osw.flush();
osw.close();
简洁的方法
FileReader fr = new FileReader("E:\\Java\\javaSE\\java.txt");
FileWriter fw = new FileWriter("E:\\Java\\javaSE\\java2.txt");
字符缓存流
//BufferWriter
FileWriter fw = new FileWriter("E:\\Java\\javaSE\\java2.txt");
BufferWriter bw = new BufferWriter(fw);
bw.writer("hello\r\n");
//BufferReader
FileReader fr = new FileReader("E:\\Java\\javaSE\\java.txt");
BufferReader br = new BufferReader(fr);
特有功能
void newLine();
//FileWriter fw = new FileWriter("E:\\Java\\javaSE\\java2.txt");
//BufferWriter bw = new BufferWriter(fw);
//bw.newLine();
String readLine();
//FileReader fr = new FileReader("E:\\Java\\javaSE\\java.txt");
//BufferReader br = new BufferReader(fr);
//String line = br.readLine();
字符流和字节流的区别
字符流只能处理文本,视频等非文本得使用字节流
字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
字节流默认不使用缓冲区;字符流使用缓冲区。
特殊操作流
标准输入流
InputStream is = System.in; //来自键盘的输入
int by;
by = is.read(); //字节流读取
InputStreamReader isr = new InputStreamReader(is); //字符流
BufferReader br = new BufferReader(isr); //字符缓存流
标准输出流
PrintStream ps = System.out; //字节打印流
PrintStream ps = new PrintStream("文件/空"); //字节打印流
ps.print("hello");
PrintWriter pw = new PrintWriter("文件/空",true(是否刷新)); //字符打印流
对象序列化流
不序列化
在值前面添加 transient修饰
private transient int age;
在对象所属类添加下列
private static finnal long serivalVersionUID= 24L;
文件修改后不会报错
将对象保存到磁盘,或者网络中传输对象
这种机制就是使用一个字节序列表示一个对象,该字节包括:对象类型、对象的数据和对象中存储的属性等信息,相当于文件中持久保存一个对象的信息
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream());
Student stu = new Student();
oos.write(stu);
对象反序列化流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream());
Object obj = ois.readObject();
Student stu = (Student)obj;
递归
方法调用方法本身的现象
多线程
继承Thread类,重写run方法
TCP UDP
Lambda表达式
new Thread(
new Runnable(){
public void run(){
sout();
}
}
);
//lambda表达式,() 里面没有内容,可以看操,方法形参为空。 ->表示后面要做的事
//{},包含一段代码,可以看成方法里面的内容
new Thread(
()->{
sout();
}
);
//格式: lambda(类型 形参)->{;}
//使用前提
//有一个接口,接口有且只有一个抽象方法
//lambda省略
//,参数类型可省略 多参数时,不能只省略一个
//Function(Flyable f) Flyable是一个抽象类,有个抽象方法add( int a,int b)
//语句只有一个时,大括号和分号 Function( (x,y)->x + y );
//如果这行代码是return语句,必须省略return不写,同时也必须省略";"不写
接口
组成
常量 public static final
抽象方法
默认方法 default不是抽象方法,但是可以被重写,重写时去掉default关键字
静态方法 public static void test(){} 静态方法只能静态类使用,实现类不能
私有方法(java 9)
方法引用
//方法引用符::
Function(s->sout(s)); //lambda表达式
Function(System.out::println);
//直接使用system.out中的println方法代替lambda
格式
类名::静态方法
函数式接口
定义
有且只有一个抽象方法的接口
函数式接口用@FunctionalInterface标注,检测接口是否是函数式接口
函数式接口就是lambda表达式的前提
MyInterface my = ()->System.out.println("函数时接口"); //lambda表达式
函数式接口作为方法的参数
Thread t = new Thread(()->{System.out.println("我是函数式接口的实现类")});
t.start();
函数式接口作为方法的返回值
//直接返回接口的匿名内部实现类
常用函数式接口
Supplier
Supper<T> 包含一个无参的方法。
T get() :获得结果;
//例子
public static void main(String[] arge){
String s = getString(()->"林青霞");
System.out.println(s);
}
private static String getString(Supplier<String> sup){
return sup.get();
}
Consumer
Consumer<T> 包含两个方法。
void accept(T t);
defaultConsumer<T> andThen(Consumer after) 返回一个组合Consumer;
Consumer<T>接口也被称为消费型接口;
//例子
public static void main(String[] arge){
operatorString("滴滴",System.out::println);
}
private static void operatorString(String name, Consumer<String> con){
con.accept(name);
}
Predicate
Predicate<T>;
方法:;
boolean test(T t):对给定的参数进行判断。返回一个布尔值;
default Predicate<T> negate():返回一个逻辑的否定,对应逻辑非;
default Predicate<T> and(Predicate other):返回一个组合判断,对应短路与;
default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或;
//例子
public static void main(String[] arge){
boolean b1 = cheakString("hello",s->s.length()>8);
}
//test
private static boolean checkString(String name, Predicate<String> pre){
return pre.test(s);
}
//and
private static boolean checkString(String name, Predicate<String> pre1,Predicate<String> pre2){
return pre1.and(pre2).test(s); //pre1.test(s) and pre2.test(s);
}
//or
private static boolean checkString(String name, Predicate<String> pre1,Predicate<String> pre2){
return pre1.or(pre2).test(s); //pre1.test(s) or pre2.test(s);
}
Function
Function<T,R> 接受一个参数并产生结果的函数。;
R apply(T t) :将此函数应用与给定的参数;
default<V> Function andThen(Function after);返回一个组合函数,首先将此函数应用于其输入,然后将after函数应用于结果。
//例子
public static void main(String[] arge){
convert("100",s->Integer.parseInt(s));
}
//apply
private static boolean convert(String s, Function<String,Integer>fun){
int i = function.apply(s);
Sout(i);
}
Stream流
Stream流的使用
生成流
//Collection体系
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
//Map体系
Map<String,Integer> map = new HashMap<String,Integer>();
Stream<String> keyStream = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String,Integer>> entryStream = map.entrySet().Stream();
//数组
String[] array = {};
Stream<String> strStream = Stream.of(array);
中间操作
//filter filter内对boolean进行判断
list.stream().filter(s ->s.startsWith("张")).forEach(System.out:println);
//limit 取前三个打印
Stream<String> s1 = list.stream().limit(3).forEach(System.out:println);
//skip 跳过前三个
Stream<String> s2 =
list.stream().skip(3).forEach(System.out:println);
//合并流
Stream<String> s3 = Stream.concat(s1,s2).forEach(System.out:println);
//排序
Stream<String> s4 =
list.stream().sorted(/*可放置comparator对象
(s1,s2)-> s1.length()-s2.length()
*/).forEach(System.out:println);
终结操作
forEach()
类
类的加载
就是将class文件读入内存,并为之创建一个java.lang.Class对象
任何类被使用时,系统都会为之建立一个java.lang.Class对象
类的链接
验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
准备阶段:负责为类的类变量分配内存,并设置默认初始化值
解析阶段:将类的二进制数据中的符号引用替换为直接引用
类的初始化步骤
假如类未被加载和链接,则程序先加载并链接该类
假如类的直接父类还违背初始化,则先初始化其直接父类
假如类中有初始化语句,则系统异常执行这些初始化语句
类的初始化时机
创建类的实例
调用类的类方法
访问类或者接口的类变量,或者为该类变量赋值
使用反射方式强制创建某个类或者接口对应的java.lang.Class对象
初始化某个类的子类
直接俄使用Java.exe命令来运行某个主类
类加载器
全盘委托
双亲委派机制
缓存机制
反射
获得Class类的对象
//1
Class<Student> c1 = Student.class;
//2
Student s = new Student();
Class<? extends Student> c2 = s.getClass();
//3
Class<?> c3 = Class.forName("com.it.Student");
获取构造方法并使用
Class<?> c = Class.forName("com.it.Student");
Constructor<?> con = c.getConstructor(/*可以有参数*/); //获得构造方法
//Constructor<?> []con = c.getConstructors(); //构造方法们
//Constructor<?> []con = c.getDeclaredConstructors();//私有的构造方法
Object obj = con.newInstance("lin",20); //生成对象
Student stu = (Student) obj;
获取成员变量
Class<?> c = Class.forName("com.it.Student");//获取class对象
Constructor<?> con = c.getConstructor(/*可以有参数*/); //获得构造方法
Object obj = con.newInstance("lin",20); //生成对象
//得先创建对象才能修改对象的成员变量
Field[] fields = c.getFields(); //获得成员变量
Field[] fields = c.getDeclaredFields(); //获得所有成员变量(含私有)
Field field = c.getField("name");
field.set(obj,"理你"); //给对象的成员变量赋值。
获取成员方法
Class<?> c = Class.forName("com.it.Student");//获取class对象
Constructor<?> con = c.getConstructor(/*可以有参数*/); //获得构造方法
Object obj = con.newInstance("lin",20); //生成对象
//得现有对象,才能使用方法
Method[] methods = c.getMethods(); //获得方法们
//Mehtod[] methods = c.getDeclaredMethods(); //获得所有方法
Method method = c.getMethod(string:"方法名", arge:String.class);
//执行方法
method.invoke(obj);
越过泛型检查
ArrayList<Integer> array = new ArrayList<Integer>();
Class<? extends ArrayList> c = array.getClass();
Method m = c.getMethod("add",Object.class);
m.invoke(array,"hello");
模块化
为了使java能够轻量化运行
使用
module myTwo{
exports 包名; //该模块暴露这个包;
provides interface with shixianlei;
}
module myOne{
requires 模块名; //调用一个模块
user interface; //调用接口
}