上一篇文章的传送门:关于一些基础的Java问题的解答(六)
import java.lang.reflect.Field; import java.lang.reflect.Method; class A { private int varA; public void myPublicA() { System.out.println("I am public in A !"); }; private void myPrivateA() { System.out.println("I am private in A !"); }; } class B extends A { public int varB; public void myPublicB(){}; } public class Main { public static void main(String[] args) throws Exception { B b = new B(); // 子类方法 Method methods[] = b.getClass().getMethods(); for (Method method : methods) System.out.println(method); System.out.println(""); // 子类变量 Field fields[] = b.getClass().getFields(); for (Field field : fields) System.out.println(field); // 基类 System.out.println("\n" + b.getClass().getSuperclass() + "\n"); // 基类private方法也不能避免 Class superClass = b.getClass().getSuperclass(); methods = superClass.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); method.setAccessible(true); // 实例化A来调用private方法! method.invoke(superClass.newInstance(), null); } } }
List<String> listString = new ArrayList<>(); // error : Type mismatch: cannot convert from List<String> to List<Object> List<Object> listObject = listString; // it's ok ! List<? extends Object> listExtendsObject = listString; // error : The method add(capture#1-of ? extends Object) in the type List<capture#1-of ? extends Object> is not applicable for the // arguments (String) listExtendsObject.add("string"); // it's ok ! listExtendsObject.add(null); // it's ok ! Object object = listExtendsObject.get(0);
class A<T,S> { }
public <T> void f(T x) { }
class A {} class B extends A {} class C {}; //代表了T为A或A的子类 class D <T extends A> {}; public class Main { public static void main(String[] args) { D<A> a; D<B> b; // no work! D<C> c; } }super与extends相反,把类型参数限制为某个类的父类。(此处博主研究不够深入,故对super关键字不够了解,在此不深入讨论)
import java.util.Arrays; class A {} class B extends A {} class C extends B {}; class D <T> { T t; D(T t) { this.t = t; } public void f() { System.out.println(Arrays.toString(this.getClass().getTypeParameters())); } }; public class Main { public static void main(String[] args) { D<A> a = new D<A>(new A()); D<B> b = new D<B>(new B()); D<C> c = new D<C>(new C()); a.f(); b.f(); c.f(); } }D中的f方法通过获取D的Class类来获取其类型信息,其打印的结果如下:
class A { public void fa() {}; } class C <T> { // 擦除到Object T t; public void f(Object a) { if (a instanceof T) {} // error,不知道具体的类型信息 T var = new T(); // error,不知道该类型是否有默认构造函数 T[] array = new T[1]; // error t.fa(); // error } }; class D <T extends A> { // 擦除到A T t; public void f(Object a) { t.fa(); // this works } };
public static void main(String[] args) throws Exception { // 桌面的xml文件,文件内容如下 // <all name="testData"> // <item first="1" second="A" third="一"/> // <item first="2" second="B" third="二"/> // <item first="3" second="C" third="三"/> // <item first="4" second="D" third="四"/> // <item first="5" second="E" third="五"/> // </all> File file = new File("C:/Users/Administrator/Desktop/test.xml"); // 文件流 FileInputStream fis = new FileInputStream(file); { // DOM解析xml System.out.println("DOM:"); // 获取DOM工厂实例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 生成builder DocumentBuilder builder = factory.newDocumentBuilder(); // 解析文件 Document document = builder.parse(file); // 获取根节点 Element element = document.getDocumentElement(); System.out.println(element.getTagName() + " " + element.getAttribute("name")); // 获取子节点列表 NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); // 节点类型为元素节点 if (node.getNodeType() == Node.ELEMENT_NODE) { Element child = (Element) node; // 输出标签名和元素内容 System.out.println(child.getTagName() + " " + child.getAttribute("first") + " " + child.getAttribute("second") + " " + child.getAttribute("third")); } } } System.out.println(""); // empty line { // SAX解析xml System.out.println("SAX:"); // 获取SAX工厂实例 SAXParserFactory factory = SAXParserFactory.newInstance(); // 获取SAX解析器 SAXParser parser = factory.newSAXParser(); // 获取reader XMLReader reader = parser.getXMLReader(); // 设置解析源和处理器 reader.setContentHandler(new MySAXHandler()); // 在parse之前设置 reader.parse(new InputSource(fis)); } } // 自定义SAX处理器 static class MySAXHandler extends DefaultHandler { @Override public void startDocument() throws SAXException { // 解析文档开始时调用 super.startDocument(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 解析元素开始时调用 // 打印元素名 System.out.print(qName); // 打印元素属性 for (int i = 0; i < attributes.getLength(); i++) System.out.print(" " + attributes.getValue(i)); System.out.println(""); super.startElement(uri, localName, qName, attributes); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 解析元素结束时调用 super.endElement(uri, localName, qName); } @Override public void endDocument() throws SAXException { // 解析文档结束时调用 super.endDocument(); } }
XmlPullParserFactory factory = XmlPullParserFactory .newInstance(); XmlPullParser xmlPullParser = factory.newPullParser(); // use gb2312 encode ByteArrayInputStream is = new ByteArrayInputStream( response.getBytes("GB2312")); xmlPullParser.setInput(is, "GB2312"); int eventType = xmlPullParser.getEventType(); String provinceName = ""; String provinceCode = ""; while (eventType != XmlPullParser.END_DOCUMENT) { String nodeName = xmlPullParser.getName(); switch (eventType) { // start parse node case XmlPullParser.START_TAG: if ("city".equals(nodeName)) { provinceName = xmlPullParser.getAttributeValue("", "quName"); provinceCode = xmlPullParser.getAttributeValue("", "pyName"); Province province = new Province(); province.setProvinceName(provinceName); province.setProvinceCode(provinceCode); coolWeatherDB.saveProvince(province); } break; default: break; } eventType = xmlPullParser.next();
Java是由C++发展而来的,保留了C++的大部分内容,其编程方式类似于C++,但是摒弃了C++的诸多不合理之处,Java是纯面向对象的编程语言。Java和C++的区别主要如下:
在Java中,一切的组件都是类与对象,没有单独的函数、方法与全局变量。C++中由于可以使用C代码,故C++中类对象与单独的函数方法共存。
在C++中类可以多重继承,但这有可能会引起菱形问题。而在Java中类不允许多重继承,一个类只能继承一个基类,但可以实现多个接口,避免了菱形问题的产生。
C++允许重载操作符,而Java不允许。
在C++中,不同的平台上,编译器对基本数据类型分别分配不同的字节数,导致了代码数据的不可移植性。在Java中,采用基于IEEE标准的数据类型,无论任何硬件平台上对数据类型的位数分配总是固定的。(然而boolean基本类型要看JVM的实现)
C++需要程序员显式地声明和释放内存。Java中有垃圾回收器,会在程序内存不足或空闲之时在后台自行回收不再使用的内存,不需要程序员管理。
指针是C++中最灵活也最容易出错的数据类型。Java中为了简单安全去掉了指针类型。
C++中,会出现数据类型的隐含转换,涉及到自动强制类型转换。Java中系统要对对象的处理进行严格的相容性检查,防止不安全的转换。如果需要,必须由程序显式进行强制类型转换。(如int类型不能直接转换为boolean类型)
C++默认的方法绑定为静态绑定,如果要使用动态绑定实现多态需要用到关键字virtual。Java默认的方法绑定为动态绑定,只有final方法和static方法为静态绑定。
目前博主就想到这么多,还有的以后再补充。
public class Main { public static void main(String[] args) throws Exception { // 动态库名字,windows平台自动拓展成makeStr_jni.dll System.loadLibrary("makeStr_jni"); // 打印字符串 printString("Java World!"); } // native关键字表示为本地方法 public static native void printString(String str); }我们在Java中使用JNI接口只需要两步:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class Main */ #ifndef _Included_Main #define _Included_Main #ifdef __cplusplus extern "C" { #endif /* * Class: Main 方法所在的类 * Method: printString 方法名 * Signature: (Ljava/lang/String;)V 签名 */ JNIEXPORT void JNICALL Java_Main_printString (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif
#include<iostream> #include"_Main.h" using namespace std; /* * JNIEnv : env JNI环境,一个提供JNI系统函数的结构体 * jclass : clazz 代表Java层的Class对象,由于printString方法是一个静态方法,故传入Class对象 * jstring : s 代表Java层的String对象,表示传入的参数 */ JNIEXPORT void JNICALL Java_Main_printString (JNIEnv * env, jclass clazz, jstring s) { jboolean iscopy; // 通过jstring对象生成本地字符串 const char *charData = env->GetStringUTFChars(s, &iscopy); // 打印字符串 cout << "A message from Native World: " << charData << endl; // 释放资源 env->ReleaseStringUTFChars(s, charData); }