当我在做项目时,我遇到了使用泛型类型的新混淆,这是对象的微妙变化。
通常,当我构造一个节点时,我声明了这样的通用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
Sample FirebaseUI App
</title>
<!-- ******************************************************************************************* * TODO(DEVELOPER): Paste the initialization snippet from: * Firebase Console > Overview > Add Firebase to your web app. * ***************************************************************************************** -->
<script type="text/javascript">
// Initialize Firebase
var config = {
apiKey: "AIzaSyB7cfgbxS4UgkGwsHyFgYwa6Ir7eRTWHM0",
authDomain: "web-teachinger.firebaseapp.com",
databaseURL: "https://web-teachinger.firebaseio.com",
projectId: "web-teachinger",
storageBucket: "",
messagingSenderId: "1070392376591"
};
firebase.initializeApp(config);
</script>
<script src="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.css" />
<script type="text/javascript">
firebase.initializeApp(config);
// FirebaseUI config.
var uiConfig = {
signInSuccessUrl: 'success.html', signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.PhoneAuthProvider.PROVIDER_ID
],
// Terms of service url.
tosUrl: 'TOS.php' };
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</head>
<body>
<!-- The surrounding HTML is left untouched by FirebaseUI. Your app may use that space for branding, controls and other customizations.-->
<h1>
Welcome to My Awesome App
</h1>
<div id="firebaseui-auth-container">
</div>
</body>
</html>
但现在,如果我这样做,这似乎也是正常的。
public class HW3<E> {
private Tree<E> treeNode = new Tree <E> ();
所以,我真的很想知道这两者之间的区别:我将Node构造为不太可能是主类对象的Object类型的不同引用。欢迎任何形式的例子。请分享您的知识。谢谢。
答案 0 :(得分:0)
在需要调用代码(外部或非外部)之前,这两种结构之间的差异并不重要。
简而言之,第一个代码将允许您的呼叫者利用泛型,而第二个代码可能不会。这仅限于treeNode
字段。
假设您要为客户端添加一个方法来检索树/对象(完全假设):
第一个版本是:
public class HW3<E> {
private Tree<E> treeNode = new Tree <E> ();
public E getNodeData();
在第一种情况下,您的客户端可以使用任何通用参数调用您的代码,而不需要强制转换:
MW3<SomeType> hw3 = ...//create instance
SomeType data = hw3.getNodeData();
Java了解这一点,并且泛型将允许您避免强制转换。
第二个版本必须是:
public class HW3<E> {
private Tree<Object> treeNode = new Tree <Object> ();
public Object getNodeData(); //You would have to do this because the field with data wouldn't know about the generic type
与使用泛型的此版本不同,如果您使用了对象,则客户端必须强制转换:
MW3<SomeType> hw3 = ...//create instance
SomeType data = (SomeType) hw3.getNodeData();
换句话说,E
类型参数在第二个示例中完全没用,您应该不使用它。
我使用的示例假设您的Tree
类型具有一些通用get
方法...
有关更多内容,请查看泛型类型实现,例如java.util.ArrayList
。您的代码段之间的主要区别在于您如何使用类型参数以及如何使您的呼叫者从中受益。
答案 1 :(得分:0)
当我们在类级定义泛型类型时,我们基本上告诉java编译器我们将在类HW3中处理类型,这是不知道的在定义时,即
public class HW3<E> {
...
}
但是根据使用情况得出,例如当你写作
HW3<Integer> myHw3OfIntegers = new HW3<Integer>();
HW3<String> myHw3OfStrings = new HW3<String>();
因此,您现在可以看到上述2个声明如何影响生成对象的treeNode
字段。第一个对象myHw3OfIntegers
将表示整数树,其中第二个对象myHw3OfStrings
将表示字符串树。