I have a public static class within another public class as follows:
public class Foo<A> {
public static class Bar<A>{
A firstBar;
Bar(A setBar){
this.firstBar=setBar;
}
}
public final Bar<A> instanceBar;
public Foo(A actualValue) {
instanceBar = new Bar<A>(actualValue);
}
public Bar<A> getBar() {
return instanceBar;
}
My objective is to access instanceBar's state from a separate class file without a get method and without changing the visibility of firstBar. How do I accomplish this?
For example, the following says not visible.
public class RetrieveFirstBar {
public static void main(String[] args) {
Foo z = new Foo(5l);
Foo.Bar<Long> z2 = z.getBar();
long k = z2.firstBar; //not visible!
}
}
I guess you mean
class Foo<A>
Since you write "A firstBar;" you give package access to the variable:
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
If you have the RetrieveFirstBar in the same package you will not have visibility problems. But, if you want to access it from everywhere you should write
public A firstBar;
Related
I'm trying to create some system with inner class. My code can be summarized to something like this.
public abstract class A {
public abstract void doSomething();
}
public class B {
public final ArrayList<A> list=new ArrayList<A>();
public B(){
}
}
public class C {
private int i;
public C(B b){
b.list.add(new A(){
public void doSomething(){
i++;
}
});
b.list.add(new A(){
public void doSomething(){
System.out.println(i);
}
});
}
}
public static void main (String[] arg) {
B manager=new B();
new C(manager);
new C(manager);
new C(manager);
}
A is abstract class that will be inherited as inner class (in my original code it is listener class), B is some kind of manager class that hold list of As, and C hold data it's data should be only modified or read by it's inner class and upon initialization it add A to the class B. Code itself works fine. But problem is as there will be various kinds of C something like C2, C3 that does different thing and this leads to my code overwhelmed with thousands of unassigned object new C(manager); this make debugging extra hard and code looks really ugly. So it seems to me my approach in the first place was wrong but have no idea how to avoid this. So how should I change my approach to not have thousands of unassigned objects?
My suggestion is: try not to use constructors to do operations that depend on state (i). Use static functions, and save the state in a separate class (we call it a “context”).
import java.util.ArrayList;
public class Demo {
// A
abstract static class InnerListener {
public abstract void onEvent();
}
// B
static class ListenerManager {
public final ArrayList<InnerListener> listeners = new ArrayList<InnerListener>();
}
static class SideEffectContext {
public int i = 0;
}
// C
static class ListenerUtil {
public static void setupListeners(ListenerManager manager, SideEffectContext context) {
manager.listeners.add(new InnerListener() {
public void onEvent() {
context.i++;
}
});
manager.listeners.add(new InnerListener() {
public void onEvent() {
System.out.println(context.i);
}
});
}
}
public static void main(String[] arg) {
var manager = new ListenerManager();
var ctxA = new SideEffectContext();
var ctxShared = new SideEffectContext();
ListenerUtil.setupListeners(manager, ctxA);
ListenerUtil.setupListeners(manager, ctxShared);
ListenerUtil.setupListeners(manager, ctxShared);
}
}
I'm working on making a programming language that compiles to JVM bytecode, and it highly relies on interfaces as types. I need some way to make an interface private, but have other code still be able to access it, but not make something that implements it.
I was thinking about using abstract classes with a private constructor, so only the classes in the same file would be able to access it. The only problem is that it is impossible to extend multiple abstract classes at once. For example, the structure of a simple compiled program would be this:
// -> Main.java
public class Main {
public static MyInteger getMyInteger() {
return new MyIntegerImpl(10);
}
public static void main(String[] args) {}
private interface MyInteger {
public int getValue();
}
private static class MyIntegerImpl implements MyInteger {
private final int value;
public int getValue() {
return value;
}
public MyIntegerImpl(int value) {
this.value = value;
}
}
}
And another file, in which there is a problem:
// -> OtherFile.java
public class OtherFile {
public static void main(String[] args) {
Main.MyInteger myInteger = Main.getMyInteger(); //Error: The type Main.MyInteger is not visible.
System.out.println(myInteger.getValue());
}
//I do not want this to be allowed
public static class sneakyInteger implements Main.MyInteger { //Error(Which is good)
public int getValue() {
System.out.println("Person accessed value");
return 10;
}
}
}
The reason why I want to do this is so one person can not mess up any other person's code by providing their own implementations of things that should be only implemented by that other person.
Any help would be much appreciated.
I'm pretty sure that you should think again about what you are trying to do and change approach, but the answer for your question is to add to the interface some empty void method that is getting the parameter of the inner private class specific for the wrapper class
public class Test {
private class InnerPrivateClass {
private InnerPrivateClass() {}
}
public interface MyInteger {
int getValue();
void accept(InnerPrivateClass c);
}
private class MyIntegerImpl implements MyInteger {
#Override
public int getValue() {
return 0;
}
#Override
public void accept(InnerPrivateClass c) {}
}
}
However, as I said, I don't like this and for me it means that your idea is broken
when you extend a private class. Are the public and protected members of class become private. if not any explanation.
if you extend a nested private class, it wont change public/protected modifiers of the members. Here is an example :
public class Clazz {
private static class NestedClazz {
public int value = 123;
}
public static class NestedClazzExt extends NestedClazz {
}
}
you can now access the inherited member: value from outside
public static void main(String[] args) {
NestedClazzExt nestedClazz = new Clazz.NestedClazzExt();
System.out.println(nestedClazz.value);
}
you can create private class in side a class . We call it as Nested classe. Means a class inside a class. The Concept itself is saying that you can create private class in side another class. The private class will act like as data member to the outer class.
So, You can't extend the private class.
Based on your query I tried to prepare a simple class.
public class pvtClass {
private class As {
public String abc = "private attribute";
public void print(){
System.out.println("privateClass");
}
}
class Ab extends As{
public String ab = "extended attribute";
public void printAb(){
System.out.println("extended class");
print();
System.out.println(abc);
}
}
public static void main(String as[]){
Ab ab1 = (new pvtClass()).new Ab();
As as1 = (new pvtClass()).new As();
ab1.printAb();
as1.print();
System.out.println(as1.abc);
}
}
If you have a look at this class, I have a private class named "As" which has public attribute and public methods. I have another class named "Ab" which extends "As". I have written a main method to invoke the private attribute and methods.
below is the output for the code snippet:
extended class
privateClass
private attribute
privateClass
private attribute
There is a difference between the access of the members of a class and the access to the type itself.
public class C {
private class InnerP1 {
public void m() {
System.out.println("InnerP1.m()");
}
}
private class InnerP2 extends InnerP1 {
public void p() {
this.m();
System.out.println("InnerP2.p()");
}
}
public InnerP1 strange() {
return new InnerP2();
}
}
In this example, the interface I is visible from outside class C. The classes InnerP1 and InnerP2 are not visible from outside C. Jave itself makes not restrictions to the visibility of types you use in your public interface. The method strange() of class C returns a result of class InnerP1. Since outside of C we do not know anything about the class InnerP1 other than it is subtype of Object, the only thing we can do is use the result of strange() as an Object.
public class D {
public static void main(String[] args) {
C c = new C();
Object o = c.strange();
if(o.equals(c.strange())) {
System.out.println("Strange things are going on here!");
}
}
}
As #KnusperPudding pointed out already, the visiblity of public members is not changed, we might just not have enough knowledge of the type itself to access them.
Access to members cannot be restricted by sub-classing. When you mark a class as private then access via the class name is restricted i.e. to the same .java file, however once you have an instance of this class it can be accessed at least as easily as the super class.
public class Test {
public static void main(String[] args) {
DemoAbstractClass abstractClass = new DemoAbstractClass() {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
};
abstractClass.runner();
/**
* I want to access getVal method here
*/
}
}
abstract class DemoAbstractClass {
public void run() {
System.out.println("running");
}
public abstract void runner();
}
Here, I'm declaring an abstract class DemoAbstractClass. I can obviously create a new class that extends this class and add this method to it. But, I would prefer not doing that in my scenario.
Is there any other way to access getVal method in above code??
You can't. You need to make a proper (non-anomous) class out of it. Make it an inner private class if you want to limit its scope.
Alternatively, you could use a StringBuffer and share a referense to it between the methods. Not extremely clean however.
Related question:
Accessing inner anonymous class members
Short of using reflection, you cannot as you have no access to the concrete type of the object to be able to bind the methodcall to
If you don want to do something like this in a sane manner, declare a named class and use that as the type of abstractClass
Unfortunately, if you cannot name the type, you cannot access the methods at the language level.
What you can do, though, is use the reflection API to get a Method object and invoke it on this object.
This, however, is pretty slow. A private class or private interface would be much faster.
I can obviously create a new class that extends this class and add this method to it.
You've already done this; the end result was an anonymous inner class: new DemoAbstractClass() { ... }; If you just moved that declaration into its own class -- you can even make it a private class -- you can access getVal.
Per your example above:
public class Test {
public static void main(String[] args) {
DemoClass abstractClass = new DemoClass();
abstractClass.runner();
/**
* I want to access getVal method here
*/
abstractClass.getVal(); // can do this here now
}
private class DemoClass extends DemoAbstractClass {
private String val;
#Override
public void runner() {
val = "test";
System.out.println(val);
this.run();
}
public String getVal() {
return val;
}
}
}
}
Another option is to make a StringBuilder a member of the main method and use the closure nature of anonymous inner methods:
public static void main(String[] args) {
final StringBuilder value = new StringBuilder();
DemoAbstractClass abstractClass = new DemoAbstractClass() {
#Override
public void runner() {
value.append( "test" );
System.out.println(val);
this.run();
}
};
abstractClass.runner();
// use val here...
String val = value.toString();
}
I am trying to understand my way around polymorphism in Java. I created a parent class that has too many common methods that all children will use in the same manner.
Each of the subclasses' children all share static information, These variables or information will be used in the methods declared only in the parent.
The problem wish accessing static variables from Parent methods seems not really possible,
Its a solution to declare the common information per instance but since there will be 1000s of instances its such a waste of memory.
A simple elaboration of what i mean is the following code :
class testParent {
static int k;
public void print()
{
System.out.println(k);
}
}
class testChild2 extends testParent
{
static
{
testChild2.k =2;
}
}
public class testChild1 extends testParent{
static
{
testChild1.k = 1;
}
public static void main(String[] args)
{
new testChild1().print();
new testChild2().print();
new testChild1().print();
}
}
the output i expect was
1
2
1.
but what happens is :
1
2
2
One might think that on the initiation of each subclass the static variables of this subclass is set and then all methods referring to this subclass has access to the corresponding 'k' value.
But what actually happens is that all subclasses edit in the same static variable that is shared along all subclasses and hence destroys my whole point of using static variables for each subclass and its instances and using commmon methods in the Parent accessing these variables.
Any idea how can this be done ?
An option is to access the subclasses' static data through an abstract (non-static) method:
abstract public class Parent {
protected abstract int getK();
public void print() {
System.out.println(getK());
}
}
public class Child1 extends Parent {
private static final int CHILD1_K = 1;
protected int getK() { return CHILD1_K; }
}
public class Child2 extends Parent {
private static final int CHILD2_K = 2;
protected int getK() { return CHILD2_K; }
}
When you make new testChild2().print(); the static block on testChield2 was executed and change the value to 2.
static blocks only execute once when loaded by the ClassLoader.
This one give the output you want:
class testParent {
static int k;
public void print()
{
System.out.println(k);
}
}
class testChild2 extends testParent
{
{
testChild2.k =2;
}
}
public class testChild1 extends testParent{
{
testChild1.k = 1;
}
public static void main(String[] args)
{
new testChild1().print();
new testChild2().print();
new testChild1().print();
}
}
Non static code blocks execute everytime the class is instanciated.
Premature optimization is the root of all evil. I don't think you'll run into any memory issues with thousands of instances, each with their own data, unless you're working on a tiny embedded system of some kind. Static variables are not intended to do what you're trying to do with them.
Static variables are specific to the class itself. If you want the same field in different instances of a class to have different values, then that field cannot be static.
The solution: don't make k static.
class testParent {
int k;
public void print()
{
System.out.println(k);
}
}
class testChild2 extends testParent
{
{
this.k =2;
}
}
class testChild1 extends testParent{
{
this.k = 1;
}
public static void main(String[] args){
new testChild1().print();
new testChild2().print();
new testChild1().print();
}
}
Demo
(ignore the static class business - that's just to make it work in ideone).