当前位置: 首页 > news >正文

Java SE

final关键字

final:最终的,可以修饰类,变量,方法


特点:
1.final修饰的类不能被继承
2.final修饰的方法不能被子类重写
3.final修饰的变量是常量

注意:
1.静态方法只能访问静态成员,如果要访问非静态成员,需要创建对象
2.非静态方法可以访问任意成员

Static关键字

static可以修饰成员变量也可以修饰成员方法,被static修饰的成员变量和成员方法是类的成员

特点:
1.静态成员可以被本类的所有对象共享
2.静态成员随着类的加载而加载,只加载一次
3.静态成员可以直接被类名调用

注意:
1.静态方法只能访问静态成员,如果要访问非静态成员,需要创建对象
2.非静态方法可以访问任意成员

public class StaticDemo {public static void main(String[] args) {Student s1=new Student();s1.name="张三";Student s2=new Student();s2.show();//我是张三,我来自nullSystem.out.println("----------------");Student.name="李四";s2.show();//我是李四,我来自nullSystem.out.println("----------------");}
}
public class Student {static String name;String school;public  void show(){System.out.println("我是"+name+",我来自"+school);}public void method1(){System.out.println(name);System.out.println(school);method2();method3();}public  void method2(){}public  static void method3(){}public static void method4(){Student s1=new Student();s1.method1();System.out.println(s1.name);System.out.println(s1.school);}
}

集合

List:有序,可重复,有索引

Set:无序,不重复,无索引

1.Collection接口方法

import java.util.*;
class CollectionMain {public static void main(String[] args) {Collection coll = new ArrayList();//清空coll.clear();coll.add(10);coll.add(20);coll.add(30);coll.add(20);// 删除指定元素coll.remove(20);//判断元素是否包含boolean b = coll.contains(10);//true//判断集合是否为空boolean b1 = coll.isEmpty();//false//判断集合的大小int size = coll.size();//3System.out.println(coll);}
}

2.迭代器

import java.util.*;
class CollectionTraversal {public static void main(String[] args) {Collection coll = new ArrayList();coll.add(10);coll.add(20);coll.add(30);coll.add(20);//1.迭代器遍历集合Iterator iterator = coll.iterator();//hasNext()判断目前位置是否有元素while (iterator.hasNext()){//next()返回当前元素并将指针移动到下一个位置Object next = iterator.next();System.out.println(next);}//2.增强for循环遍历集合for(Object a:coll){System.out.println(a);}//3.lambda表达式遍历集合coll.forEach(a -> System.out.println(a));}
}

3.List集合特有方法

import java.util.ArrayList;
import java.util.List;//List集合方法
public class ListFn {public static void main(String[] args) {List<String> list = new ArrayList();//添加元素list.add("a");list.add("b");list.add("c");list.add("d");//在指定位置添加元素list.add(2,"e");System.out.println(list);//获取元素System.out.println(list.get(0));//获取元素的索引System.out.println(list.indexOf("b"));//获取最后一个元素的索引System.out.println(list.lastIndexOf("b"));//判断元素是否存在System.out.println(list.contains("a"));//判断集合是否为空System.out.println(list.isEmpty());//获取集合的大小System.out.println(list.size());//删除元素list.remove("a");list.remove(0);System.out.println(list);//修改元素list.set(0,"f");System.out.println(list);}
}

 4.ArrayList

底层原理:

1.新创建的集合,底层为长度为0的数组

2.添加第一个元素时,底层创建一个新的长度为10的数组

3.存满时,扩容1.5倍

4.一次添加多个数据,1.5倍放不下,则新创建的长度以实际为准

5.LinkedList

底层是双链表,查询快,增删慢

6.Set集合

HashSet:无序,不重复,无索引

LinkedHashSet:有序,不重复,无索引

TreeSet:可排序,不重复,无索引

7.HashSet

jdk8以前:数组+链表

1.创建一个默认长度16,默认加载因子0.75的数组

2.计算出应存入的位置

3.判断该位置是否为null,如果是null直接存入

4.如果不是null,调用equals比较属性值

5.一样:不存   不一样:存入,形成链表

jdk8以后:数组+链表+红黑树(链表长度超过8,数组长度大于64)

如果没有重写hashCode方法,不同对象计算出的哈希值是不同的

如果已经重写hashCode方法,不同对象属性相同,计算出的哈希值相同

8.LinkedHashSet

有序、不重复、无索引

原理:底层数据结构是哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序。

9.TreeSet

s1可排序、不重复、无索引,集合底层是基于红黑树的数据结构实现排序,其增删改查性能都较好

public class TreeSetTest {public static void main(String[] args) {TreeSet<Integer> treeSet = new TreeSet<>();treeSet.add(5);treeSet.add(10);treeSet.add(12);treeSet.add(1);treeSet.add(7);System.out.println(treeSet);//[1, 5, 7, 10, 12]}
}

TreeSet比较规则

import java.util.TreeSet;
public class TreeSetTest {public static void main(String[] args) {//1.javabean类实现Comparable接口指定比较规则(自然排序)默认//2.创建TreeSet对象的时候,传递比较器Comparator指定规则TreeSet<Student> treeSet = new TreeSet<>((o1, o2) -> o1.getAge() - o2.getAge());treeSet.add(new Student("张三",18));treeSet.add(new Student("李四",19));treeSet.add(new Student("王五",17));treeSet.forEach(System.out::println);}
}

10.Map

11.HashMap

源码:

先算出存储元素的地址值
如果地址值不一样,直接根据hash值当下标存储到表中
如果地址值一样,根据hash值当下标存储,
如果当前位置为空,直接存储
如果当前位置有数据,调用equals比较内容是否相同
如果内容相同,不存
如果内容不相同,在同一位置形成链表,存储如下

12.LinkedHashMap

有序,不重复,无索引

13.TreeMap

可排序,不重复,无索引

14.Collections集合工具类

public class TreeSetTest {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();//Collections.addAll()方法可以将数组中的元素添加到集合中Collections.addAll(list,"f","b","c","d");System.out.println(list);//Collections.shuffle()方法可以随机打乱集合中的元素Collections.shuffle(list);System.out.println(list);//Collections.sort()方法可以对集合中的元素进行排序Collections.sort(list);System.out.println(list);//Collections.max()方法可以获取集合中的最大值String max = Collections.max(list);System.out.println(max);}
}

异常

 Error:系统级别异常(不用管),例如内存溢出

Exception:

        RuntimeException:编译阶段不会出现提示,例如数组越界

        运行时异常:编译就会报错

抛出异常

throws:写在方法定义处,表示声明一个异常,告诉调用者使用本方法可能有哪些异常

throw:写在方法里,将异常抛给调用者

自定义异常

目的:让报错信息更见名知意

1.定义异常类

2.写继承关系

3.空参构造

4.带参构造

public class NameException extends RuntimeException {public NameException( ) {}public NameException(String message) {super(message);}
}

多线程

并发:同一时刻,多个指令在单个cpu交替执行

并行:同一时刻,多个指令在多个cpu同时执行

实现多线程方式

1.继承Thread类

public class MyThread extends Thread{@Overridepublic void run() {for(int i=0;i<100;i++){System.out.println(getName() +"123");}}
}
    public static void main(String[] args) {MyThread T1 = new MyThread();T1.setName("t1");MyThread T2 = new MyThread();T2.setName("t2");T1.start();T2.start();}

2.实现Runnable

public class MyThread implements Runnable{@Overridepublic void run() {for(int i=0;i<100;i++){//getName是Thread的方法,实现Runnable的话不可用Thread thread = Thread.currentThread();//获取当前线程String name = thread.getName();System.out.println(name+"123");}}
}
    public static void main(String[] args) {//创建多线程要执行的任务MyThread T = new MyThread();//创建线程对象Thread thread1 = new Thread(T);Thread thread2 = new Thread(T);thread2.setName("T1");thread1.setName("T2");thread1.start();thread2.start();}

3.多线程

特点:可以获得多线程的返回结果

        1.创建类实现Callable接口

        2.重写call方法(表示多线程的返回值)

        3.创建任务对象

        4.创建FutureTask的对象(管理多线程的运行结果)

        5.创建THread的对象,并启动

public class MyThread implements Callable<Integer> {@Overridepublic Integer call() {return 100;}
}
    public static void main(String[] args) throws Exception {//创建多线程要执行的任务MyThread T = new MyThread();//创建FutureTask对象FutureTask<Integer> task = new FutureTask<>(T);//创建线程对象Thread T1 =new Thread(task);//启动线程T1.start();//获取结果Integer integer = task.get();System.out.println(integer);}

多线程中的常见成员方法

1.获取线程名

getName()

public class MyThread extends Thread {@Overridepublic void run() {System.out.println(getName());}
}

2.设置线程名

setName()

    public static void main(String[] args) throws Exception {MyThread myThread = new MyThread();myThread.setName("T1");myThread.start();}

3.获取当前线程对象

Thread.currentThread

    public static void main(String[] args) throws Exception {Thread thread = Thread.currentThread();thread.setName("AA");System.out.println(thread.getName());}

4.线程休眠

Thread.sleep(1000)

5.设置线程优先级

getPriority,setPriority

    public static void main(String[] args) throws Exception {MyThread myThread = new MyThread();MyThread myThread1 = new MyThread();//获取当前线程优先级  int priority = myThread.getPriority();//设置优先级myThread.setPriority(10);myThread1.setPriority(1);myThread1.start();myThread.start();}

6.守护线程

setDaemon

设置某个线程为守护线程后,若其他线程执行完成,守护线程会陆续结束

    public static void main(String[] args) throws Exception {MyThread T1 = new MyThread();MyThread T2 = new MyThread();//设置T2为守护线程T2.setDaemon(true);T1.start();T2.start();}

7.礼让线程

public class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName()+i);//出让cpu礼让权Thread.yield();}}
}

8.插队线程

join()

    public static void main(String[] args) throws Exception {MyThread T1 = new MyThread();T1.setName("线程一");T1.start();//表示把T1线程插入到当前线程之前//先执行完T1,在执行Main,不会交替T1.join();for (int i = 0; i < 100; i++) {System.out.println("Main");}}

线程的生命周期

同步代码块

synchronized 

public class MyThread extends Thread {static Object o = new Object();@Overridepublic void run() {synchronized (o){System.out.println();}}
}

Lock锁

可以手动获得锁和手动释放锁

new 锁

       static Lock lock=new ReentrantLock();

获得锁

            lock.lock();

 释放锁

            lock.unlock();

线程池

无限线程池

    public static void main(String[] args) throws Exception {//1.创建线程池对象ExecutorService pool1 = Executors.newCachedThreadPool();//无上限线程池//2.创建任务对象MyThread myThread = new MyThread();//3.提交任务pool1.submit(myThread);//4销毁线程池pool1.shutdown();}

有限线程池

        //1.创建有三个线程的线程池对象ExecutorService pool1 = Executors.newFixedThreadPool(3);

自定义线程池

    public static void main(String[] args) throws Exception {
//        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor();
//        参数一:核心线程数
//        参数二:最大线程数
//        参数三:空闲线程的最大存活时间
//        参数四:时间单位
//        参数五:任务队列
//        参数六:创建线程工厂
//        参数七:任务的拒绝策略ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,  //核心线程数6,  //最大线程数60, //空闲线程的最大存活时间TimeUnit.SECONDS, //时间单位new ArrayBlockingQueue<>(3), //任务队列Executors.defaultThreadFactory(), //创建线程工厂new ThreadPoolExecutor.AbortPolicy() //任务的拒绝策略);}

类型转换

 字符串--->基本类型

基本类型=基本类型的包装类.parseInt(字符串);

例如

        int num1 = Integer.parseInt("123");long num2 = Long.parseLong("123456");double num3 = Double.parseDouble("3.14");boolean flag = Boolean.parseBoolean("true");

字符串/基本类型--->包装类

包装类=包装类.valueOf()

        Integer i = Integer.valueOf("456");Long l = Long.valueOf(789L);Double d = Double.valueOf("9.8");Boolean b = Boolean.valueOf(false);

泛型&可变参数

泛型类

//自定义泛型类
public class MyList<E> {
Object[] obj=new Object[10];
int size;
public boolean add(E e){
obj[size]=e;
size++;
return true;
}
public E get(int index){
return (E)obj[index];
}
}

泛型方法

import java.util.ArrayList;
//泛型方法
public class fangxingFn {public static <E> void addAll(ArrayList<E> list,E e1,E e2){list.add(e1);list.add(e2);}
}

可变参数

public class Test  {public static int add(int ...a){//可变参数底层是一个数组int len=a.length;int sum=0;for (int i = 0; i < len; i++) {sum+=a[i];}return sum;}
}

 Java IO流

存储和读取数据
按流向分为输出流和输入流、
按操作文件类型分为字节流(所有文件)和字符流(文本文件)

字节流

字节输出流

步骤:

1.创建字节输出流对象

		OutputStream os = new FileOutputStream("E:\\apps\\1.txt");

2.写出数据

		os.write(99);

3.释放资源

		os.close();
细节

1.创建字节输出流的对象

        1.参数是字符串或者File对象都可以
2.如果文件不存在会自动创建,但要保证父级路径存在
3.如果文件已经存在,会清空文件

2.write的参数是整数,写到文件中的是ASCII的字符

3.使用完流后要释放资源

FileOutputStream写数据的3种方法
	void contextLoads() throws Exception {OutputStream os = new FileOutputStream("E:\\apps\\1.txt");//一次写一个os.write(99);// 'c'//写一个字节数组byte[] bytes={97,98,99,100,101};os.write(bytes);//写一个字节数组的一部分os.write(bytes,0,2);os.close();}
换行和续写

换行

	@Testvoid contextLoads() throws Exception {OutputStream os = new FileOutputStream("E:\\apps\\1.txt");//写一个字节数组byte[] bytes = "abcdef".getBytes();os.write(bytes);//写一个换行符//	'\r\n'os.write("\r\n".getBytes());byte[] bytes2 = "ghijkl".getBytes();os.write(bytes2);os.close();}

续写

new FileOutputStream()的第二个参数,默认是false,表示关闭续写,改为true,表示创建对象时不会清空文件。

	@Testvoid contextLoads() throws Exception {OutputStream os = new FileOutputStream("E:\\apps\\1.txt",true);//写一个字节数组byte[] bytes = "abcdef".getBytes();os.write(bytes);os.close();}

字节输入流

步骤:

1.创建字节输入流对象

InputStream is = new FileInputStream("E:\\apps\\1.txt");

2.读数据

一次是读一个数据

int read = is.read();

3.释放资源

is.close();
细节

1.创建字节输入流的对象
1.如果文件不存在会报错

2.读数据

        1.read 一次读一个字节,读出来的是数据在ASCII上对应的数字

        2.读到文件末尾,read返回-1

3.使用完流后要释放资源

FileInputStream一次读多个字节
public int read(byte[] buffer)

字符流

字符流=字节流+字符集

输入流:一次读一个字节,遇到汉字,一次读多个

输出流:把数据按指定方式编码,变成字节再写到文件中

字符输出流

read():

GBK一次读两个字节,UTF-8一次读三字节,读到后返回二进制转为十进制后的值

读多个数据

传入字节数组改为传入字符数组

	void contextLoads() throws Exception {FileReader fr=new FileReader("E:\\apps\\1.txt");//读多个数据fr.read(new char[2]);}

字符输入流

字节缓冲流

创建字节缓冲流

	void contextLoads() throws Exception {
//普通流FileInputStream fr=new FileInputStream("E:\\apps\\1.txt");
//缓冲流BufferedInputStream bufferedInputStream = new BufferedInputStream(fr);
//普通流FileOutputStream fileOutputStream = new FileOutputStream("E:\\apps\\1.txt");
//缓冲流BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);}

字节缓冲流原理

字符缓冲流

创建字符缓冲流

转化流

转化流是字符流和字节流之间的桥梁

序列化流

把java对象写到本地文件

1.要写入的对象实现Serializable接口

	void contextLoads() throws Exception {Student student = new Student("张三", 18);ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("E:\\apps\\1.txt"));objectOutputStream.writeObject(student);objectOutputStream.close();}

反序列流

	@Testvoid contextLoads() throws Exception {ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("E:\\apps\\1.txt"));Student student = (Student) objectInputStream.readObject();System.out.println(student);}

Java 反射

什么是反射?

反射允许对成员变量,成员方法和构造方法的信息编程访问。

获取class对象的三种方法

        Class Clazz1 = Class.forName("com.example.demo.Student");Class Clazz2 = Student.class;Class Clazz3 = new Student().getClass();

反射获取构造方法

Constructor constructor1 = Clazz1.getDeclaredConstructor():        获取单个构造方法(无参)

Constructor constructor1 = Clazz1.getDeclaredConstructor(String.slass):        获取单个构造方法(只有一个参数,且是String类型)

Constructor constructor1 = Clazz1.getDeclaredConstructor(int.class):        获取单个构造方法(只有一个参数,且是int类型)

获得构造方法的权限修饰符

Constructor constructor1 = Clazz1.getDeclaredConstructor();int modifiers = constructor1.getModifiers();

获得构造方法的参数

        Class Clazz1 = Class.forName("com.example.demo.Student");Constructor constructor1 = Clazz1.getDeclaredConstructor(String.class);Parameter[] parameters = constructor1.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter);}

通过反射获得的构造函数获取对象

使用构造函数对象的newInstance方法

        Class Clazz1 = Class.forName("com.example.demo.Student");Constructor constructor1 = Clazz1.getDeclaredConstructor(String.class);Student o = (Student) constructor1.newInstance("张三");System.out.println(o);

暴力反射

如果构造方法是私有的,Declared仅仅能让看到这个构造方法,但还是用不了,要使用的话,要对构造方法对象使用setAccessible(true);暂时取消这个限制,叫做暴力反射。

        Class Clazz1 = Class.forName("com.example.demo.Student");Constructor constructor1 = Clazz1.getDeclaredConstructor(String.class,int.class);constructor1.setAccessible(true);Student o = (Student) constructor1.newInstance("张三",20);System.out.println(o);

反射获取成员变量

通过变量名获取成员变量

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Field field = Clazz1.getField("name");System.out.println(field);}

获取成员变量的名字

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Field field = Clazz1.getField("name");String name = field.getName();System.out.println(name);}

获取对象记录的值

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Field field = Clazz1.getField("name");//获取成员变量记录的值Student student = new Student("张三", 20);field.get(student);}

修改成员变量记录的值                                                                                                                                                                                               

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Field field = Clazz1.getField("name");//修改成员变量记录的值Student student = new Student("张三", 20);field.set(student,"李四");System.out.println(student);}

反射获取成员方法          

获取指定的单个方法

因为方法重载的可能,所以不仅要指定方法名,还要指定方法的参数类型

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Method method = Clazz1.getMethod("sleep", String.class);System.out.println(method);}

获取方法的形参

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Method method = Clazz1.getMethod("sleep", String.class);//获取方法的形参Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter);}}

方法运行

    public String to(String name){System.out.println(name);return "返回值";}

使用方法.invoke(对象,参数)调用方法

    public static void main(String[] args) throws Exception {Class Clazz1 = Class.forName("com.example.demo.Student");Method method = Clazz1.getMethod("to", String.class);Student student = new Student();String re = (String) method.invoke(student, "订单");System.out.println(re);}

Java 注解

注解让其他程序根据注解信息来决定如何执行该程序

声明使用注解

声明注解

public @interface t {String aaa();int bbb();
}

使用

@t(aaa="ttt",bbb = 1)
public class Student  {@t(aaa="qqq",bbb=2)public void test(){}
}

如果只有一个value属性可以简写为

public @interface t {String value();
}
@t("ttt")
public class Student  {
}

元注解

修饰注解的注解

//声明注解的保留周期
@Retention(RetentionPolicy.RUNTIME)
//注明注解可以用在哪些地方
@Target(ElementType.ANNOTATION_TYPE)
public @interface zj {
}

注解的解析

要解析谁上面的注解,就应该先拿到谁

比如要解析类上的注解,就要先获得类的Class对象

要解析方法的注解,就要先获得方法的Method对象

@zj(value = "装载机",aaa = 99,bbb = {"这种","那种"})
public class Student  {@zj(value = "悟空",aaa = 77,bbb = {"这边","那边"})public void test(){}
}
public class DemoApplication {public static void main(String[] args) throws Exception {//1.获得class对象Class aClass = Student.class;//2.解析//判断类上是否包含某个注解if(aClass.isAnnotationPresent(zj.class)){//获得注解zj declaredAnnotation = (zj) aClass.getDeclaredAnnotation(zj.class);//获得注解的值String value = declaredAnnotation.value();double aaa = declaredAnnotation.aaa();String[] bbb = declaredAnnotation.bbb();System.out.println(value);System.out.println(aaa);System.out.println(Arrays.toString(bbb));}}
}

Stream流

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamTest {public static void main(String[] args) {//1.单列集合获取StreamList<Integer> list = new ArrayList<>();Collections.addAll(list,1,2,3,4,5,1);list.stream().forEach(item-> System.out.println(item));//2.双列集合获取StreamMap<String, Integer> map = new HashMap<>();map.put("aaa",111);map.put("bbb",222);map.put("ccc",333);map.put("ddd",444);map.put("eee",555);//获取键的流map.keySet().stream().forEach(item-> System.out.println(item));//以键值对形式放入流map.entrySet().stream().forEach(item-> System.out.println(item));//3.数组获取Streamint[] arr1 = {1,2,3,4,5};Arrays.stream(arr1).forEach(item-> System.out.println(item));System.out.println("------------------------");//filter 过滤list.stream().filter(item->item>3).forEach(item-> System.out.println(item));System.out.println("------------------------");//limit list.stream().limit(3)表示查找前三个list.stream().limit(3).forEach(item-> System.out.println(item));System.out.println("------------------------");//skip list.stream().skip(3)表示跳过前三个list.stream().skip(3).forEach(item-> System.out.println(item));System.out.println("------------------------");//distinct 去重list.stream().distinct().forEach(item-> System.out.println(item));System.out.println("------------------------");//concat 合并流Stream.concat(list.stream(),list.stream()).forEach(item-> System.out.println(item));System.out.println("------------------------");//map 操作流中的每个元素list.stream().map(item->item*2).forEach(item-> System.out.println(item));System.out.println("------------------------");//Stream的终结方法//1.count 统计System.out.println(list.stream().count());//2.collect 收集Set<Integer> list2 = list.stream().collect(Collectors.toSet());System.out.println(list2);}
}
http://www.dtcms.com/a/401469.html

相关文章:

  • 怎么做网站软件滨州做网站多少钱
  • 网站开发兼职合同福田专业网站建设公司
  • 英文网站优化怎么制作免费的企业网站
  • 网页设计资料下载网站定制网站建设价格
  • 永州内部网站建设公司网站开发背景论文
  • 帮别人备案网站武邑网站建设
  • 建站工具上市港港网app下载最新版
  • 做网站用php如何学习谷歌广告代理
  • 网站 模板下载wordpress 短代码失效
  • 支持手机网站的空间用dw做的网站怎么上传
  • 浙江网站建设与维护书parallax wordpress
  • 网站设计评级安庆建设银行网站
  • 网站建设报告总结品牌建设部
  • 济南网站建设李尚荣模板网站seo
  • 东莞网站建设服务有什么用开发网站做图文水印逻辑
  • 网站建设怎样上传程序手机代码网站有哪些问题吗
  • 用wordpress制作网站图案设计网
  • 网站编程学习网页版微信登陆
  • 网站建设 cn歌曲网站源码
  • 无锡网站推广公司排名哈尔滨工程招投标信息网
  • 1有免费建网站站酷做网站
  • 地产网站互动营销新昌建设局网站
  • 住房和城乡建设部执法网站湛江做网站说
  • 网站域名实名认证临汾做网站
  • 潍坊网站建设解决方案wordpress插件无法安装插件
  • 柯桥区建设集团网站建阳网站建设wzjseo
  • 网站开发+自动生成缩略图保定建设局网站
  • 网站右侧二维码代码网站页面做成自适应优缺点
  • 怎么做电商卖东西东莞市网络seo推广服务机构
  • 四川网站建设的公司排名磁力搜索器 磁力猫在线